import { router, useLocalSearchParams } from 'expo-router';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Alert, Image, ImageBackground, Pressable, Share, StyleSheet, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import { formatMoney } from '@navi/ui';
import type { BookingKind, ListingKind, Room } from '@navi/types';
import { NaviHeader } from '../../src/components/layout/NaviHeader';
import { PrimaryButton } from '../../src/components/PrimaryButton';
import { Screen } from '../../src/components/Screen';
import { StateView } from '../../src/components/StateView';
import { api } from '../../src/api/client';
import { useAuth } from '../../src/state/auth';
import { useLocale } from '../../src/state/locale';
import { imageForListing, naviAssets } from '../../src/assets/naviAssets';
import { color, radius, spacing, typography } from '../../src/theme';

export default function Listing() {
  const { t } = useTranslation();
  const { id } = useLocalSearchParams<{ id: string }>();
  const locale = useLocale((s) => s.locale);
  const user = useAuth((s) => s.user);
  const queryClient = useQueryClient();
  const listing = useQuery({
    queryKey: ['listing', id],
    queryFn: () => api.listings.byId(String(id)),
    enabled: !!id,
  });
  const saved = useQuery({
    queryKey: ['saved'],
    queryFn: () => api.saved.list(),
    enabled: !!user,
  });
  const savedIds = new Set((saved.data ?? []).filter((item) => item.refType === 'LISTING').map((item) => item.refId));
  const isSaved = listing.data ? savedIds.has(listing.data.id) : false;

  const toggleSave = useMutation({
    mutationFn: async () => {
      if (!listing.data) return;
      if (!user) {
        Alert.alert(t('listing.signInRequired'), t('listing.signInToSave'));
        router.push('/(auth)/login');
        return;
      }
      if (isSaved) await api.saved.remove('LISTING', listing.data.id);
      else await api.saved.add('LISTING', listing.data.id);
    },
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['saved'] }),
  });

  const createBooking = useMutation({
    mutationFn: async () => {
      if (!listing.data) return null;
      if (!user) {
        Alert.alert(t('listing.signInRequired'), t('listing.signInToBook'));
        router.push('/(auth)/login');
        return null;
      }
      const kind = bookingKindFor(listing.data.kind);
      if (!kind) return null;
      return api.bookings.create({
        listingId: listing.data.id,
        kind,
        guestCount: 1,
      });
    },
    onSuccess: (booking) => {
      if (!booking) return;
      queryClient.invalidateQueries({ queryKey: ['bookings'] });
      Alert.alert(t('listing.bookingStarted'), t('listing.bookingStartedBody'));
      router.push('/(tabs)/bookings');
    },
  });

  if (listing.isLoading) {
    return (
      <Screen>
        <NaviHeader variant="center" title={t('listing.title')} showBack onBack={() => router.replace('/(tabs)/discover')} />
        <StateView tone="loading" title={t('listing.loading')} />
      </Screen>
    );
  }

  if (listing.isError) {
    return (
      <Screen>
        <NaviHeader variant="center" title={t('listing.title')} showBack onBack={() => router.replace('/(tabs)/discover')} />
        <StateView tone="error" title={t('listing.unavailableTitle')} body={t('listing.unavailableBody')} />
      </Screen>
    );
  }

  if (!listing.data) {
    return (
      <Screen>
        <NaviHeader variant="center" title={t('listing.title')} showBack onBack={() => router.replace('/(tabs)/discover')} />
        <StateView tone="empty" title={t('listing.notFoundTitle')} body={t('listing.notFoundBody')} />
      </Screen>
    );
  }

  const item = listing.data;
  const bookingKind = bookingKindFor(item.kind);
  const heroSource = imageForListing(item) ?? (item.coverImageUrl ? { uri: item.coverImageUrl } : naviAssets.destinations.homeHero);

  return (
    <Screen>
      <ImageBackground source={heroSource} style={styles.hero} imageStyle={styles.heroImage}>
        <NaviHeader
          variant="transparentImage"
          showBack
          onBack={() => router.replace('/(tabs)/discover')}
          actions={[
            {
              kind: 'share',
              label: t('listing.share'),
              onPress: () => {
                void Share.share({ message: t('listing.shareMessage', { title: item.title }) });
              },
            },
            { kind: 'heart', label: isSaved ? t('listing.unsave') : t('listing.save'), onPress: () => toggleSave.mutate(), active: isSaved },
          ]}
        />
      </ImageBackground>

      <View style={styles.titleRow}>
        <View style={styles.titleCopy}>
          <Text style={styles.kind}>{labelForKind(item.kind, t)}</Text>
          <Text style={styles.h1}>{item.title}</Text>
          <Text style={styles.meta}>{t('listing.review', { rating: item.ratingAverage.toFixed(1), count: item.ratingCount })}</Text>
        </View>
        <Pressable style={styles.saveButton} onPress={() => toggleSave.mutate()} accessibilityRole="button">
          <Text style={[styles.saveText, isSaved ? styles.savedText : null]}>{isSaved ? t('listing.saved') : t('actions.save')}</Text>
        </Pressable>
      </View>

      <Text style={styles.summary}>{item.summary}</Text>

      <View style={styles.priceCard}>
        <Text style={styles.priceLabel}>{item.kind === 'STAY' ? t('listing.fromPerNight') : t('listing.from')}</Text>
        <Text style={styles.priceValue}>{item.priceFrom.amountMinor > 0 ? formatMoney(item.priceFrom, locale) : t('listing.quoteRequired')}</Text>
      </View>

      {item.rooms.length ? (
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>{t('listing.available')}</Text>
          {item.rooms.map((room, index) => <RoomCard key={room.id} room={room} locale={locale} index={index} />)}
        </View>
      ) : null}

      {item.kind === 'PHARMACY' ? (
        <View style={styles.compliance}>
          <Text style={styles.complianceText}>{t('listing.compliancePharmacy')}</Text>
        </View>
      ) : null}

      {bookingKind ? (
        <PrimaryButton
          label={createBooking.isPending ? t('listing.startingBooking') : item.kind === 'STAY' ? t('actions.selectRoom') : t('actions.bookNow')}
          onPress={() => (item.kind === 'STAY' ? router.push(`/rooms/${item.id}`) : createBooking.mutate())}
          disabled={createBooking.isPending}
          rightIcon
        />
      ) : (
        <StateView
          tone="empty"
          title={t('listing.orderDisabledTitle')}
          body={t('listing.orderDisabledBody')}
        />
      )}
    </Screen>
  );
}

function RoomCard({ room, locale, index }: { room: Room; locale: 'en' | 'ar'; index: number }) {
  const { t } = useTranslation();
  const image = index % 2 === 0 ? naviAssets.hotels.skyViewSuite : naviAssets.hotels.palmVista;
  return (
    <View style={styles.roomCard}>
      <Image source={image} style={styles.roomImage} resizeMode="cover" />
      <Text style={styles.roomTitle}>{room.name}</Text>
      <Text style={styles.roomMeta}>{t('rooms.meta', { guests: room.capacity, sqm: room.sqm, bed: room.bedConfig })}</Text>
      <Text style={styles.roomPrice}>{t('rooms.perNight', { price: formatMoney(room.price, locale) })}</Text>
    </View>
  );
}

function bookingKindFor(kind: ListingKind): BookingKind | null {
  if (kind === 'STAY') return 'STAY';
  if (kind === 'ACTIVITY') return 'ACTIVITY';
  if (kind === 'TAXI_TIER') return 'TAXI_RIDE';
  return null;
}

function labelForKind(kind: ListingKind, t: (key: string) => string): string {
  switch (kind) {
    case 'STAY':
      return t('listing.kind.stay');
    case 'ACTIVITY':
      return t('listing.kind.activity');
    case 'TAXI_TIER':
      return t('listing.kind.taxi');
    case 'RESTAURANT':
      return t('listing.kind.restaurant');
    case 'PHARMACY':
      return t('listing.kind.pharmacy');
    case 'GROCERY':
      return t('listing.kind.grocery');
    case 'SIM_PLAN':
      return t('listing.kind.sim');
  }
}

const styles = StyleSheet.create({
  hero: {
    backgroundColor: color.bg[100],
    borderRadius: radius.xl,
    height: 280,
    overflow: 'hidden',
    width: '100%',
  },
  heroImage: {
    borderRadius: radius.xl,
  },
  titleRow: {
    alignItems: 'flex-start',
    flexDirection: 'row',
    gap: spacing[3],
    justifyContent: 'space-between',
  },
  titleCopy: {
    flex: 1,
    gap: spacing[1],
  },
  kind: {
    color: color.blue[600],
    fontSize: typography.scale.caption.size,
    fontWeight: '900',
  },
  h1: {
    color: color.ink[900],
    fontSize: typography.scale.h1.size,
    fontWeight: '900',
    lineHeight: 34,
  },
  meta: {
    color: color.ink[500],
    fontSize: typography.scale.caption.size,
    fontWeight: '700',
  },
  saveButton: {
    backgroundColor: color.bg[0],
    borderColor: color.border,
    borderRadius: radius.pill,
    borderWidth: 1,
    paddingHorizontal: spacing[4],
    paddingVertical: spacing[2],
  },
  saveText: {
    color: color.ink[700],
    fontWeight: '800',
  },
  savedText: {
    color: color.danger,
  },
  summary: {
    color: color.ink[700],
    fontSize: typography.scale.body.size,
    lineHeight: 23,
  },
  priceCard: {
    backgroundColor: color.bg[0],
    borderColor: color.border,
    borderRadius: radius.xl,
    borderWidth: 1,
    padding: spacing[5],
  },
  priceLabel: {
    color: color.ink[500],
    fontWeight: '700',
  },
  priceValue: {
    color: color.blue[600],
    fontSize: typography.scale.h2.size,
    fontWeight: '900',
    marginTop: spacing[1],
  },
  section: {
    gap: spacing[3],
  },
  sectionTitle: {
    color: color.ink[900],
    fontSize: typography.scale.h3.size,
    fontWeight: '900',
  },
  roomCard: {
    backgroundColor: color.bg[0],
    borderColor: color.border,
    borderRadius: radius.lg,
    borderWidth: 1,
    gap: spacing[1],
    padding: spacing[4],
  },
  roomImage: {
    borderRadius: radius.md,
    height: 144,
    marginBottom: spacing[2],
    width: '100%',
  },
  roomTitle: {
    color: color.ink[900],
    fontWeight: '900',
  },
  roomMeta: {
    color: color.ink[500],
    fontSize: typography.scale.caption.size,
  },
  roomPrice: {
    color: color.blue[600],
    fontWeight: '900',
    marginTop: spacing[1],
  },
  compliance: {
    backgroundColor: '#FFF4DE',
    borderColor: '#FFE0A3',
    borderRadius: radius.lg,
    borderWidth: 1,
    padding: spacing[4],
  },
  complianceText: {
    color: '#7A4B00',
    fontSize: typography.scale.caption.size,
    fontWeight: '700',
    lineHeight: 19,
  },
});
