import React, { useState, useMemo } from 'react';
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Alert } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useRoute, useNavigation } from '@react-navigation/native';
import { useApp } from '../context/AppContext';
import { Card } from '../components/ui/Card';
import { Button } from '../components/ui/Button';
import { currency } from '../lib/format';
import { colors, radius, shadows } from '../lib/theme';

export default function Booking() {
  const route = useRoute();
  const navigation = useNavigation();
  const { shopId, serviceId: initialServiceId } = route.params as { shopId: string; serviceId?: string };
  const { shops, shopsReady, createAppointment, user, appointments, waitlists, joinWaitlist } = useApp();

  const shop = useMemo(() => shops.find((s) => s.id === shopId), [shops, shopId]);

  const [step, setStep] = useState(initialServiceId ? 2 : 1);
  const [serviceId, setService] = useState(initialServiceId || '');
  const [barberId, setBarber] = useState('');
  const [date, setDate] = useState(new Date().toISOString().split('T')[0]);
  const [slot, setSlot] = useState('');
  const [reminderMinutes, setReminderMinutes] = useState(60);

  const selectedService = shop?.services.find((s) => s.id === serviceId);
  const selectedBarber = shop?.barbers.find((b) => b.id === barberId);
  const stepLabels = ['Serviço', 'Equipa', 'Dia', 'Confirmar'];

  const availableDates = useMemo(() => {
    const dates = [];
    const today = new Date();
    for (let i = 0; i < 14; i++) {
      const d = new Date();
      d.setDate(today.getDate() + i);
      dates.push({
        full: d.toISOString().split('T')[0],
        day: d.getDate(),
        weekday: d.toLocaleDateString('pt-PT', { weekday: 'short' }).replace('.', '').toUpperCase(),
      });
    }
    return dates;
  }, []);

  const generateDefaultSlots = (): string[] => {
    const slots: string[] = [];
    for (let hour = 9; hour <= 18; hour += 1) {
      slots.push(`${hour.toString().padStart(2, '0')}:00`);
      if (hour < 18) slots.push(`${hour.toString().padStart(2, '0')}:30`);
    }
    return slots;
  };

  const isShopClosedOnDate = useMemo(() => {
    if (!date || !shop) return false;
    const dateObj = new Date(`${date}T00:00:00`);
    const ptDays = ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'];
    const dayName = ptDays[dateObj.getDay()];

    const exception = shop.schedule?.find((s) => s.isException && s.date === date);
    if (exception) return Boolean(exception.closed);

    const defaultDay = shop.schedule?.find((s) => !s.isException && (s.day === dayName || s.day.startsWith(dayName.slice(0, 3))));
    if (defaultDay) return Boolean(defaultDay.closed);

    return dayName === 'Domingo';
  }, [shop?.schedule, date]);

  const processedSlots = useMemo(() => {
    if (!selectedBarber || !date || isShopClosedOnDate) return [];

    const specificSchedule = selectedBarber.schedule?.find((s) => s.day === date);
    const slots =
      specificSchedule && specificSchedule.slots.length > 0
        ? [...specificSchedule.slots]
        : generateDefaultSlots();

    const bookedSlots = appointments
      .filter((apt) => apt.barberId === barberId && apt.status !== 'cancelado' && apt.date.startsWith(date))
      .map((apt) => apt.date.split(' ')[1])
      .filter(Boolean);

    const todayStr = new Date().toISOString().split('T')[0];
    const isToday = date === todayStr;
    const now = new Date();

    return slots.map((time) => {
      let isPast = false;
      if (isToday) {
        const [h, m] = time.split(':').map(Number);
        if (h < now.getHours() || (h === now.getHours() && m <= now.getMinutes())) {
          isPast = true;
        }
      }
      const isBooked = bookedSlots.includes(time) || isPast;
      const waitlistedByMe = user
        ? waitlists.some(
            (w) =>
              w.barberId === barberId &&
              w.date.startsWith(date) &&
              w.customerId === user.id &&
              w.status === 'pending'
          )
        : false;
      return { time, isBooked, waitlistedByMe };
    });
  }, [selectedBarber, date, barberId, appointments, user, waitlists, isShopClosedOnDate]);

  const submit = async () => {
    if (!user) { navigation.navigate('Login' as never); return; }
    const appt = await createAppointment({
      shopId: shop!.id,
      serviceId,
      barberId,
      customerId: user.id,
      date: `${date} ${slot}`,
      reminderMinutes
    });
    if (appt) {
      Alert.alert('Sucesso', 'O seu agendamento foi confirmado.');
      navigation.navigate('ExploreTab' as never);
    } else {
      Alert.alert('Erro', 'Não foi possível criar a marcação. O horário pode já estar ocupado.');
    }
  };

  if (!shopsReady && !shop) {
    return (
      <SafeAreaView style={[styles.container, styles.centered]}>
        <Text style={styles.loadingText}>A preparar reserva...</Text>
      </SafeAreaView>
    );
  }

  if (!shop) return null;

  return (
    <SafeAreaView style={styles.container}>
      {/* Header Estilizado */}
      <View style={styles.header}>
        <TouchableOpacity onPress={() => step > 1 ? setStep(s => s - 1) : navigation.goBack()} style={styles.backBtn}>
          <Text style={styles.backIcon}>←</Text>
        </TouchableOpacity>
        <View style={styles.headerTitleBox}>
          <Text style={styles.headerTitle}>Agendamento</Text>
          <Text style={styles.headerSubtitle}>Etapa {step} de 4</Text>
        </View>
        <View style={{ width: 40 }} />
      </View>

      <ScrollView contentContainerStyle={styles.scrollContent}>
        <View style={styles.stepTracker}>
          {stepLabels.map((label, index) => {
            const stepNumber = index + 1;
            const active = stepNumber === step;
            const done = stepNumber < step;
            return (
              <View key={label} style={styles.stepTrackItem}>
                <View style={[styles.stepDot, active && styles.stepDotActive, done && styles.stepDotDone]}>
                  <Text style={[styles.stepDotText, (active || done) && styles.stepDotTextActive]}>
                    {done ? '✓' : stepNumber}
                  </Text>
                </View>
                <Text style={[styles.stepTrackLabel, active && styles.stepTrackLabelActive]} numberOfLines={1}>
                  {label}
                </Text>
              </View>
            );
          })}
        </View>

        <Card style={styles.contextCard}>
          <View style={styles.contextHeader}>
            <Text style={styles.contextKicker}>A marcar em</Text>
            <Text style={styles.contextTitle} numberOfLines={1}>{shop.name}</Text>
          </View>
          <View style={styles.contextGrid}>
            <View style={styles.contextCell}>
              <Text style={styles.contextLabel}>Serviço</Text>
              <Text style={styles.contextValue} numberOfLines={1}>{selectedService?.name || 'Por escolher'}</Text>
            </View>
            <View style={styles.contextCell}>
              <Text style={styles.contextLabel}>Profissional</Text>
              <Text style={styles.contextValue} numberOfLines={1}>{selectedBarber?.name || 'Por escolher'}</Text>
            </View>
          </View>
        </Card>

        {step === 1 && (
          <View style={styles.stepBox}>
            <Text style={styles.stepLabel}>Escolha o serviço</Text>
            {shop.services.map(s => (
              <TouchableOpacity key={s.id} onPress={() => { setService(s.id); setStep(2); }}>
                <Card style={[styles.choiceCard, serviceId === s.id && styles.choiceCardActive]}>
                  <View style={{ flex: 1 }}>
                    <Text style={styles.choiceName}>{s.name}</Text>
                    <Text style={styles.choiceMeta}>{s.duration} min</Text>
                  </View>
                  <View style={styles.pricePill}>
                    <Text style={styles.choicePrice}>{currency(s.price)}</Text>
                  </View>
                </Card>
              </TouchableOpacity>
            ))}
          </View>
        )}

        {step === 2 && (
          <View style={styles.stepBox}>
            <Text style={styles.stepLabel}>Com quem prefere?</Text>
            {shop.barbers.map(b => (
              <TouchableOpacity key={b.id} onPress={() => { setBarber(b.id); setStep(3); }}>
                <Card style={[styles.choiceCard, barberId === b.id && styles.choiceCardActive]}>
                  <View style={styles.avatarMini}><Text style={styles.avatarTxt}>{b.name.charAt(0)}</Text></View>
                  <View style={{ flex: 1 }}>
                    <Text style={styles.choiceName}>{b.name}</Text>
                    <Text style={styles.choiceMeta}>{b.specialties[0] || 'Profissional'}</Text>
                  </View>
                </Card>
              </TouchableOpacity>
            ))}
          </View>
        )}

        {step === 3 && (
          <View style={styles.stepBox}>
            <Text style={styles.stepLabel}>Escolha o dia</Text>
            <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.dateList}>
              {availableDates.map(d => (
                <TouchableOpacity key={d.full} onPress={() => setDate(d.full)} style={[styles.dateItem, date === d.full && styles.dateItemActive]}>
                  <Text style={[styles.dateWeek, date === d.full && styles.dateTextActive]}>{d.weekday}</Text>
                  <Text style={[styles.dateDay, date === d.full && styles.dateTextActive]}>{d.day}</Text>
                </TouchableOpacity>
              ))}
            </ScrollView>

            <Text style={[styles.stepLabel, { marginTop: 20 }]}>Horários disponíveis</Text>
            {isShopClosedOnDate ? (
              <View style={styles.closedBox}>
                <Text style={styles.closedTitle}>O estabelecimento está fechado neste dia.</Text>
                <Text style={styles.closedHint}>Selecione outra data.</Text>
              </View>
            ) : processedSlots.some((s) => !s.isBooked) ? (
              <View style={styles.slotsGrid}>
                {processedSlots.filter((s) => !s.isBooked).map((s) => (
                  <TouchableOpacity
                    key={s.time}
                    onPress={() => setSlot(s.time)}
                    style={[styles.slotItem, slot === s.time && styles.slotActive]}
                  >
                    <Text style={[styles.slotText, slot === s.time && styles.slotTextActive]}>{s.time}</Text>
                  </TouchableOpacity>
                ))}
              </View>
            ) : processedSlots.length > 0 ? (
              <View style={styles.closedBox}>
                <Text style={styles.closedTitle}>Todos os horários estão preenchidos.</Text>
                {processedSlots.some((s) => s.waitlistedByMe) ? (
                  <Text style={styles.closedHint}>Já estás na lista de espera deste dia.</Text>
                ) : (
                  <Button
                    size="sm"
                    variant="dark"
                    onPress={async () => {
                      if (!user) {
                        navigation.navigate('Login' as never);
                        return;
                      }
                      const ok = await joinWaitlist(shop.id, serviceId, barberId, `${date} ${processedSlots[0]?.time || '09:00'}`);
                      Alert.alert(
                        ok ? 'Lista de espera' : 'Erro',
                        ok ? 'Entraste na lista de espera! Serás notificado se houver desistências.' : 'Não foi possível entrar na lista de espera.'
                      );
                    }}
                  >
                    Entrar na Lista de Espera
                  </Button>
                )}
              </View>
            ) : (
              <Text style={styles.closedHint}>Sem horários para este dia.</Text>
            )}
            
            {slot !== '' && (
              <View style={styles.footerAction}>
                <Text style={styles.selectedSlot}>Selecionado: {slot}</Text>
                <Button onPress={() => setStep(4)}>Continuar</Button>
              </View>
            )}
          </View>
        )}

        {step === 4 && (
          <View style={styles.stepBox}>
            <Text style={styles.stepLabel}>Confirmar detalhes</Text>
            <Card style={styles.summaryCard}>
              <View style={styles.summaryRow}><Text style={styles.summaryLabel}>Serviço</Text><Text style={styles.summaryValue}>{selectedService?.name}</Text></View>
              <View style={styles.summaryRow}><Text style={styles.summaryLabel}>Barbeiro</Text><Text style={styles.summaryValue}>{selectedBarber?.name}</Text></View>
              <View style={styles.summaryRow}><Text style={styles.summaryLabel}>Data</Text><Text style={styles.summaryValue}>{date}</Text></View>
              <View style={styles.summaryRow}><Text style={styles.summaryLabel}>Hora</Text><Text style={styles.summaryValue}>{slot}</Text></View>
              <View style={styles.divider} />
              <View style={styles.summaryRow}><Text style={styles.summaryLabel}>Total</Text><Text style={styles.summaryTotal}>{currency(selectedService?.price || 0)}</Text></View>
            </Card>

            <Text style={[styles.stepLabel, { marginTop: 24 }]}>Lembrete</Text>
            <View style={styles.notifOptions}>
              {[15, 30, 60, 120].map(m => (
                <TouchableOpacity key={m} onPress={() => setReminderMinutes(m)} style={[styles.notifBtn, reminderMinutes === m && styles.notifBtnActive]}>
                  <Text style={[styles.notifBtnTxt, reminderMinutes === m && styles.notifBtnTxtActive]}>
                    {m >= 60 ? `${m/60}h antes` : `${m}m antes`}
                  </Text>
                </TouchableOpacity>
              ))}
            </View>

            <Button style={{ marginTop: 32 }} onPress={submit}>Confirmar Agendamento</Button>
          </View>
        )}
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.background,
  },
  centered: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  loadingText: {
    color: colors.textMuted,
    fontWeight: '700',
  },
  closedBox: {
    backgroundColor: colors.dangerSoft,
    borderRadius: radius.lg,
    borderWidth: 1,
    borderColor: '#fecaca',
    padding: 20,
    gap: 10,
    alignItems: 'center',
  },
  closedTitle: {
    color: colors.danger,
    fontWeight: '800',
    textAlign: 'center',
  },
  closedHint: {
    color: colors.textMuted,
    fontSize: 13,
    textAlign: 'center',
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 20,
    paddingVertical: 12,
    backgroundColor: colors.surface,
    borderBottomWidth: 1,
    borderBottomColor: colors.border,
  },
  backBtn: {
    width: 40,
    height: 40,
    borderRadius: radius.md,
    backgroundColor: colors.surfaceMuted,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1,
    borderColor: colors.border,
  },
  backIcon: {
    color: colors.text,
    fontSize: 20,
    fontWeight: '700',
  },
  headerTitleBox: {
    alignItems: 'center',
  },
  headerTitle: {
    color: colors.text,
    fontSize: 18,
    fontWeight: '800',
  },
  headerSubtitle: {
    color: colors.textMuted,
    fontSize: 12,
    fontWeight: '600',
  },
  scrollContent: {
    padding: 20,
    paddingBottom: 40,
    gap: 18,
  },
  stepBox: {
    gap: 12,
  },
  stepTracker: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    backgroundColor: colors.surface,
    borderRadius: radius.sm,
    borderWidth: 1,
    borderColor: colors.border,
    padding: 12,
    ...shadows.soft,
  },
  stepTrackItem: {
    flex: 1,
    alignItems: 'center',
    gap: 6,
  },
  stepDot: {
    width: 30,
    height: 30,
    borderRadius: radius.pill,
    backgroundColor: colors.surfaceMuted,
    borderWidth: 1,
    borderColor: colors.border,
    alignItems: 'center',
    justifyContent: 'center',
  },
  stepDotActive: {
    backgroundColor: colors.primary,
    borderColor: colors.primary,
  },
  stepDotDone: {
    backgroundColor: colors.surfaceDark,
    borderColor: colors.surfaceDark,
  },
  stepDotText: {
    color: colors.textMuted,
    fontSize: 12,
    fontWeight: '900',
  },
  stepDotTextActive: {
    color: colors.textInverse,
  },
  stepTrackLabel: {
    color: colors.textMuted,
    fontSize: 11,
    fontWeight: '700',
  },
  stepTrackLabelActive: {
    color: colors.text,
  },
  contextCard: {
    gap: 14,
    padding: 16,
  },
  contextHeader: {
    gap: 2,
  },
  contextKicker: {
    color: colors.textMuted,
    fontSize: 12,
    fontWeight: '800',
    textTransform: 'uppercase',
  },
  contextTitle: {
    color: colors.text,
    fontSize: 20,
    fontWeight: '900',
  },
  contextGrid: {
    flexDirection: 'row',
    gap: 10,
  },
  contextCell: {
    flex: 1,
    backgroundColor: colors.surfaceMuted,
    borderRadius: radius.sm,
    padding: 10,
    borderWidth: 1,
    borderColor: colors.border,
  },
  contextLabel: {
    color: colors.textMuted,
    fontSize: 11,
    fontWeight: '800',
    textTransform: 'uppercase',
    marginBottom: 4,
  },
  contextValue: {
    color: colors.text,
    fontSize: 13,
    fontWeight: '800',
  },
  stepLabel: {
    color: colors.textMuted,
    fontSize: 12,
    fontWeight: '800',
    textTransform: 'uppercase',
    letterSpacing: 0,
    marginBottom: 8,
  },
  choiceCard: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 16,
    gap: 14,
    borderWidth: 1,
    borderColor: colors.border,
  },
  choiceCardActive: {
    borderColor: colors.primary,
    backgroundColor: colors.primarySoft,
  },
  choiceName: {
    color: colors.text,
    fontSize: 16,
    fontWeight: '700',
  },
  choiceMeta: {
    color: colors.textMuted,
    fontSize: 13,
  },
  choicePrice: {
    color: colors.primaryDark,
    fontSize: 14,
    fontWeight: '800',
  },
  pricePill: {
    backgroundColor: colors.primarySoft,
    borderRadius: radius.pill,
    paddingHorizontal: 10,
    paddingVertical: 6,
  },
  avatarMini: {
    width: 44,
    height: 44,
    borderRadius: radius.md,
    backgroundColor: colors.primarySoft,
    alignItems: 'center',
    justifyContent: 'center',
  },
  avatarTxt: {
    color: colors.primary,
    fontSize: 18,
    fontWeight: '900',
  },
  dateList: {
    gap: 10,
  },
  dateItem: {
    width: 64,
    height: 80,
    borderRadius: radius.sm,
    backgroundColor: colors.surface,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1,
    borderColor: colors.border,
    ...shadows.soft,
  },
  dateItemActive: {
    backgroundColor: colors.primary,
    borderColor: colors.primary,
  },
  dateWeek: {
    color: colors.textMuted,
    fontSize: 10,
    fontWeight: '800',
  },
  dateDay: {
    color: colors.text,
    fontSize: 20,
    fontWeight: '900',
    marginTop: 4,
  },
  dateTextActive: {
    color: colors.textInverse,
  },
  slotsGrid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  slotItem: {
    width: '22.5%',
    height: 44,
    borderRadius: radius.md,
    backgroundColor: colors.surface,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1,
    borderColor: colors.border,
  },
  slotActive: {
    backgroundColor: colors.primary,
    borderColor: colors.primary,
  },
  slotBooked: {
    opacity: 0.2,
  },
  slotText: {
    color: colors.textMuted,
    fontSize: 14,
    fontWeight: '700',
  },
  slotTextActive: {
    color: colors.textInverse,
  },
  slotTextBooked: {
    textDecorationLine: 'line-through',
  },
  summaryCard: {
    padding: 20,
    gap: 12,
  },
  summaryRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  summaryLabel: {
    color: colors.textMuted,
    fontSize: 14,
  },
  summaryValue: {
    color: colors.text,
    fontSize: 14,
    fontWeight: '700',
  },
  divider: {
    height: 1,
    backgroundColor: colors.border,
    marginVertical: 4,
  },
  summaryTotal: {
    color: colors.primary,
    fontSize: 22,
    fontWeight: '900',
  },
  notifOptions: {
    flexDirection: 'row',
    gap: 10,
  },
  notifBtn: {
    flex: 1,
    paddingVertical: 12,
    borderRadius: radius.md,
    backgroundColor: colors.surface,
    alignItems: 'center',
    borderWidth: 1,
    borderColor: colors.border,
  },
  notifBtnActive: {
    backgroundColor: colors.primarySoft,
    borderColor: colors.primary,
  },
  notifBtnTxt: {
    color: colors.textMuted,
    fontSize: 12,
    fontWeight: '700',
  },
  notifBtnTxtActive: {
    color: colors.primaryDark,
  },
  footerAction: {
    backgroundColor: colors.surface,
    borderRadius: radius.sm,
    borderWidth: 1,
    borderColor: colors.border,
    padding: 14,
    gap: 12,
    ...shadows.soft,
  },
  selectedSlot: {
    color: colors.textMuted,
    fontSize: 13,
    fontWeight: '700',
    textAlign: 'center',
  },
});
