import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
import { API_ENDPOINTS, buildApiUrl } from '@/assets/config/api';
import { useAuth } from '@/assets/contexts/useAuth';
import ConfirmadasIcon from '@/assets/icons/icon-reservas-confirmadas.svg';
import MalaIcon from '@/assets/icons/icon-mala.svg';
import TotalReservasIcon from '@/assets/icons/icon-total-reservas.svg';
import WifiIcon from '@/assets/icons/wifi-solid.svg';
import { downloadDocumentos, getDocumentosChecksums, verificarDocumentosParaDownload } from '@/assets/services/documentSync';
import { cacheReservas, getCachedReservas } from '@/assets/services/offlineStorage';
import { colors } from '@/assets/styles/colors';
import { Reserva, ReservasResponse } from '@/assets/types';
import styles from '@/styles/screens/tabs/home.styles';
import { FontAwesome } from '@expo/vector-icons';
import { Href, router } from 'expo-router';
import { useEffect, useMemo, useState } from 'react';
import {
    Alert,
    Image,
    Pressable,
    RefreshControl,
    ScrollView,
    Text,
    View,
} from 'react-native';

const getStatusPriority = (statusCode: string): number => {
  switch (statusCode) {
    case '10':
      return 1; // Em viagem
    case '1':
    case '5':
      return 2; // Confirmada
    case '-1':
      return 3; // Em pagamento
    case '-2':
    case '-3':
      return 4; // Pendente
    case '99':
      return 5; // Viagem realizada
    case '-5':
      return 7; // Cancelada — sempre no fim
    default:
      return 6;
  }
};

type HomeFilter = 'proxima' | 'total' | 'confirmadas';

const sortReservas = (items: Reserva[]) =>
  [...items].sort((a, b) => {
    const priorityDiff = getStatusPriority(a.statusCode) - getStatusPriority(b.statusCode);
    if (priorityDiff !== 0) return priorityDiff;
    return new Date(a.startDate).getTime() - new Date(b.startDate).getTime();
  });

export default function Home() {
  const { token } = useAuth();
  const [reservas, setReservas] = useState<Reserva[]>([]);
  const [activeFilter, setActiveFilter] = useState<HomeFilter>('total');
  const [isLoading, setIsLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isFromCache, setIsFromCache] = useState(false);

  const syncDocumentos = async () => {
    if (!token) return;
    try {
      const checksumsData = await getDocumentosChecksums(token);
      if (!checksumsData || checksumsData.status !== 200 || !checksumsData.documentos?.length) return;

      const documentosParaDownload = await verificarDocumentosParaDownload(checksumsData.documentos);
      if (!documentosParaDownload.length) return;

      Alert.alert(
        'Documentos disponíveis',
        `Existem ${documentosParaDownload.length} ficheiro${documentosParaDownload.length === 1 ? '' : 's'} novo${documentosParaDownload.length === 1 ? '' : 's'} para descarregar/atualizar. Pretende descarregá-los agora?`,
        [
          { text: 'Não', style: 'cancel' },
          {
            text: 'Sim',
            onPress: () => downloadDocumentos(documentosParaDownload),
          },
        ],
      );
    } catch {
      // sync de documentos é silencioso — não bloqueia o utilizador
    }
  };

  const fetchReservas = async () => {
    try {
      setError(null);

      if (!token) {
        setReservas([]);
        setIsFromCache(false);
        return;
      }

      const url = buildApiUrl(API_ENDPOINTS.USER_RESERVAS);
      const formData = new FormData();
      formData.append('token', token);

      const response = await fetch(url, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
        },
        body: formData,
      });

      
      const data: ReservasResponse = await response.json();

      if (!response.ok || (data.status !== 200 && data.status !== '200')) {
        throw new Error(data.message || 'Erro ao carregar reservas');
      }

      const orderedReservas = sortReservas(data.reservas || []);

      setReservas(orderedReservas);
      setIsFromCache(false);
      await cacheReservas(orderedReservas);
      syncDocumentos();
    } catch {
      const cached = await getCachedReservas();
      if (cached && cached.length > 0) {
        setReservas(cached);
        setIsFromCache(true);
        setError(null);
      } else {
        setError('Sem ligação à internet e sem dados guardados.');
      }
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    setReservas([]);
    setIsFromCache(false);
    setIsLoading(true);
    fetchReservas();
  }, [token]);

  const onRefresh = async () => {
    setRefreshing(true);
    await fetchReservas();
    setRefreshing(false);
  };

  const stats = useMemo(() => {
    const now = new Date();
    const proximas = reservas.filter((reserva) => new Date(reserva.startDate) >= now);
    const total = reservas.length;
    const confirmadas = reservas.filter(
      (reserva) => reserva.statusCode === '1' || reserva.statusCode === '5'
    ).length;
    const proxima = sortReservas(proximas)[0];

    let dias = '--';
    if (proxima) {
      const diff = new Date(proxima.startDate).getTime() - now.getTime();
      dias = `${Math.max(0, Math.ceil(diff / (1000 * 60 * 60 * 24)))}`;
    }

    const reservaEmViagem = reservas.find((reserva) => reserva.statusCode === '10');

    return {
      dias,
      total,
      confirmadas,
      emViagem: Boolean(reservaEmViagem),
      destinoEmViagem: reservaEmViagem?.destino?.trim() || '—',
      reservaEmViagem,
      proximaReserva: proxima ?? null,
    };
  }, [reservas]);

  const filteredReservas = useMemo(() => {
    const now = new Date();

    if (activeFilter === 'total') {
      return sortReservas(reservas);
    }

    if (activeFilter === 'confirmadas') {
      return sortReservas(
        reservas.filter(
          (reserva) => reserva.statusCode === '1' || reserva.statusCode === '5'
        )
      );
    }

    if (stats.reservaEmViagem) {
      return [stats.reservaEmViagem];
    }

    const proxima = reservas
      .filter((reserva) => new Date(reserva.startDate) >= now)
      .sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime())[0];

    return proxima ? [proxima] : [];
  }, [activeFilter, reservas, stats.reservaEmViagem]);

  const sectionTitle = useMemo(() => {
    if (activeFilter === 'confirmadas') return 'Reservas Confirmadas';
    if (activeFilter === 'proxima') {
      return stats.emViagem ? 'Em Viagem' : 'Próxima Viagem';
    }
    return 'As minhas Reservas';
  }, [activeFilter, stats.emViagem]);

  const emptyMessage = useMemo(() => {
    if (activeFilter === 'confirmadas') return 'Sem reservas confirmadas.';
    if (activeFilter === 'proxima') {
      return stats.emViagem
        ? 'Sem viagem em curso.'
        : 'Sem viagens futuras para apresentar.';
    }
    return 'Sem reservas para apresentar.';
  }, [activeFilter, stats.emViagem]);

  const getStatusType = (statusCode: string) => {
    if (statusCode === '1' || statusCode === '5') return 'verde';
    if (statusCode === '-5') return 'vermelho';
    if (statusCode === '10' || statusCode === '99') return 'roxo';
    if (statusCode === '-2' || statusCode === '-1' || statusCode === '-3') return 'amarelo';
    return 'neutral';
  };

  const getStatusColor = (statusType: string) => {
    switch (statusType) {
      case 'verde':
        return '#13AE45';
      case 'vermelho':
        return '#E6463B';
      case 'roxo':
        return '#B138E6';
      case 'amarelo':
        return '#C99700';
      default:
        return '#4A6592';
    }
  };

  const getStatusConfig = (statusCode: string) => {
    switch (statusCode) {
      case '1':
        return { label: 'Confirmada', icon: 'check-circle' as const };
      case '5':
        return { label: 'Confirmada*', icon: 'check-circle' as const };
      case '-5':
        return { label: 'Cancelada', icon: 'times-circle' as const };
      case '10':
        return { label: 'Em Viagem', icon: 'ship' as const };
      case '99':
        return { label: 'Viagem Realizada', icon: 'ship' as const };
      case '-2':
      case '-3':
        return { label: 'Pendente', icon: 'clock-o' as const };
      case '-1':
        return { label: 'Em pagamento', icon: 'clock-o' as const };
      default:
        return { label: 'Não definido', icon: 'question-circle' as const };
    }
  };

  if (isLoading) {
    return (
      <View style={styles.centered}>
        <LoadingSpinner size="large" />
      </View>
    );
  }

  const isProximaActive = activeFilter === 'proxima';
  const isTotalActive = activeFilter === 'total';
  const isConfirmadasActive = activeFilter === 'confirmadas';

  return (
    <View style={styles.container}>
      <ScrollView
        contentContainerStyle={styles.content}
        showsVerticalScrollIndicator={false}
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>

        <View style={styles.statsRow}>
          <Pressable
            style={[styles.statCard, isProximaActive && styles.statCardPrimary]}
            onPress={() => setActiveFilter('proxima')}>
            {stats.emViagem ? (
              <View style={styles.statIconEmViagemWrap}>
                <FontAwesome name="ship" size={20} color={colors.azul} />
              </View>
            ) : isProximaActive ? (
              <Image source={require('@/assets/icons/mala.png')} style={styles.statIcon} />
            ) : (
              <MalaIcon width={38} height={38} style={styles.statIconSvg} />
            )}
            <Text style={isProximaActive ? styles.statLabelPrimary : styles.statLabel}>
              {stats.emViagem ? 'Em viagem' : 'Proxima Viagem'}
            </Text>
            <Text
              style={isProximaActive ? styles.statValuePrimary : styles.statValue}
              numberOfLines={stats.emViagem ? 2 : 1}>
              {stats.emViagem ? stats.destinoEmViagem : `${stats.dias} dias`}
            </Text>
          </Pressable>

          <Pressable
            style={[styles.statCard, isTotalActive && styles.statCardPrimary]}
            onPress={() => setActiveFilter('total')}>
            {isTotalActive ? (
              <TotalReservasIcon width={38} height={38} style={styles.statIconSvg} />
            ) : (
              <Image source={require('@/assets/icons/calendario.png')} style={styles.statIcon} />
            )}
            <Text style={isTotalActive ? styles.statLabelPrimary : styles.statLabel}>
              Total Reservas
            </Text>
            <Text style={isTotalActive ? styles.statValuePrimary : styles.statValue}>
              {stats.total}
            </Text>
          </Pressable>

          <Pressable
            style={[styles.statCard, isConfirmadasActive && styles.statCardPrimary]}
            onPress={() => setActiveFilter('confirmadas')}>
            {isConfirmadasActive ? (
              <ConfirmadasIcon width={38} height={38} style={styles.statIconSvg} />
            ) : (
              <Image source={require('@/assets/icons/confirmadas.png')} style={styles.statIcon} />
            )}
            <Text style={isConfirmadasActive ? styles.statLabelPrimary : styles.statLabel}>
              Confirmadas
            </Text>
            <Text style={isConfirmadasActive ? styles.statValuePrimary : styles.statValue}>
              {stats.confirmadas}
            </Text>
          </Pressable>
        </View>

        {isFromCache && (
          <View style={styles.offlineBanner}>
            <WifiIcon width={13} height={13} fill={colors.branco} />
            <Text style={styles.offlineBannerText}>Sem ligação — a mostrar dados guardados</Text>
          </View>
        )}

        <Text style={styles.sectionTitle}>{sectionTitle}</Text>

        {!!error && <Text style={styles.errorText}>{error}</Text>}

        {!error && filteredReservas.length === 0 && (
          <Text style={styles.emptyText}>{emptyMessage}</Text>
        )}

        {!error &&
          filteredReservas.map((reserva, index) => {
            const statusType = getStatusType(reserva.statusCode);
            const statusConfig = getStatusConfig(reserva.statusCode);
            const statusColor = getStatusColor(statusType);
            return (
              <Pressable
                key={`${reserva.referenciaViagem}-${index}`}
                style={styles.card}
                onPress={() =>
                  router.push(`/reserva/${encodeURIComponent(reserva.referenciaViagem || '')}` as Href)
                }>
                <Image
                  source={
                    reserva.imagemCidade
                      ? { uri: reserva.imagemCidade }
                      : require('@/assets/icons/logo.png')
                  }
                  style={styles.cardImage}
                />
                <View style={styles.cardContent}>
                  <View style={styles.cardTopRow}>
                    <Text style={styles.refText}>{reserva.referenciaViagem || '---'}</Text>
                    <View
                      style={[
                        styles.statusBadge,
                        statusType === 'verde' && styles.statusSuccess,
                        statusType === 'vermelho' && styles.statusDanger,
                        statusType === 'roxo' && styles.statusInfo,
                        statusType === 'amarelo' && styles.statusPendente,
                      ]}>
                      <View style={styles.statusBadgeContent}>
                        <FontAwesome name={statusConfig.icon} size={12} color={statusColor} />
                        <Text
                          numberOfLines={1}
                          ellipsizeMode="tail"
                          style={[
                            styles.statusText,
                            statusType === 'verde' && styles.statusTextSuccess,
                            statusType === 'vermelho' && styles.statusTextDanger,
                            statusType === 'roxo' && styles.statusTextInfo,
                            statusType === 'amarelo' && styles.statusTextPendente,
                          ]}>
                          {statusConfig.label}
                        </Text>
                      </View>
                    </View>
                  </View>

                  <Text style={styles.destination} numberOfLines={1} ellipsizeMode="tail">
                    {reserva.destino}
                  </Text>
                  <Text style={styles.meta}><FontAwesome name="map" size={12} color="#4A6592" /> {reserva.pais}</Text>
                  <View style={styles.dateRow}>
                    <FontAwesome name="calendar" size={12} color="#4A6592" />
                    <Text style={styles.meta}>{reserva.startDate}</Text>
                  </View>
                </View>
                <View style={styles.arrowWrap}>
                  <FontAwesome name="angle-right" size={20} color="#EB2415" />
                </View>
              </Pressable>
            );
          })}
      </ScrollView>
    </View>
  );
}