import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
import { DashedDivider } from '@/assets/components/reserva/DashedDivider';
import { DocumentoRow } from '@/assets/components/reserva/DocumentoRow';
import {
    formatCurrency,
    formatDateLong,
    formatDateShort,
    getImageUrl,
} from '@/assets/components/reserva/formatters';
import { HotelCard } from '@/assets/components/reserva/HotelCard';
import { PassageiroCard } from '@/assets/components/reserva/PassageiroCard';
import { Section } from '@/assets/components/reserva/Section';
import { StatusBadge } from '@/assets/components/reserva/StatusBadge';
import { ValorReservaCard } from '@/assets/components/reserva/ValorReservaCard';
import { VooCard } from '@/assets/components/reserva/VooCard';
import { API_ENDPOINTS, buildApiUrl } from '@/assets/config/api';
import { useAuth } from '@/assets/contexts/useAuth';
import WifiIcon from '@/assets/icons/wifi-solid.svg';
import { colors } from '@/assets/styles/colors';
import { cacheReservaFull, getCachedReservaFull } from '@/assets/services/offlineStorage';
import {
    Documento,
    Escala,
    JsonData,
    Pagamento,
    ReservaData,
    ReservaResponse,
    VooDirection,
    VooSegment,
} from '@/assets/types';
import styles from '@/styles/screens/reserva/detail.styles';
import { Stack, useLocalSearchParams } from 'expo-router';
import React, { useEffect, useMemo, useState } from 'react';
import {
    Image,
    RefreshControl,
    ScrollView,
    Text,
    View,
} from 'react-native';

export default function ReservaDetalheScreen() {
  const { referencia } = useLocalSearchParams<{ referencia: string }>();
  const { token } = useAuth();
  const [isLoading, setIsLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [reservaData, setReservaData] = useState<ReservaData | null>(null);
  const [pagamentos, setPagamentos] = useState<Pagamento[]>([]);
  const [documentos, setDocumentos] = useState<Documento[]>([]);
  const [expandedPassageiros, setExpandedPassageiros] = useState<Set<number>>(new Set());
  const [cachedAt, setCachedAt] = useState<string | null>(null);
  const [isFromCache, setIsFromCache] = useState(false);

  const togglePassageiro = (idx: number) => {
    setExpandedPassageiros((prev) => {
      const next = new Set(prev);
      if (next.has(idx)) {
        next.delete(idx);
      } else {
        next.add(idx);
      }
      return next;
    });
  };

  const fetchReserva = async () => {
    try {
      setError(null);
      if (!token || !referencia) {
        throw new Error('Dados de autenticacao em falta');
      }

      const formData = new FormData();
      formData.append('token', token);
      formData.append('referenciaViagem', referencia);

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

      const data: ReservaResponse = await response.json();
      if (!response.ok || data.status !== 200 || !data.reserva) {
        throw new Error(data.message || 'Nao foi possivel carregar a reserva');
      }

      const pagamentosData = data.pagamentos || [];
      const documentosData = data.documentos || [];
      const now = new Date().toISOString();

      setReservaData(data.reserva);
      setPagamentos(pagamentosData);
      setDocumentos(documentosData);
      setCachedAt(now);
      setIsFromCache(false);

      await cacheReservaFull(referencia, {
        reservaData: data.reserva,
        pagamentos: pagamentosData,
        documentos: documentosData,
        cachedAt: now,
      });
    } catch {
      const cached = await getCachedReservaFull(referencia);
      if (cached) {
        setReservaData(cached.reservaData);
        setPagamentos(cached.pagamentos);
        setDocumentos(cached.documentos);
        setCachedAt(cached.cachedAt);
        setIsFromCache(true);
        setError(null);
      } else {
        setError('Sem ligação à internet e sem dados guardados para esta reserva.');
      }
    } finally {
      setIsLoading(false);
    }
  };

  function metodosPagamento($metodo: string) {
    switch ($metodo) {
      case 'mb':
        return 'Multibanco';
      case 'mbway':
        return 'MB Way';
      case 'cc':
        return 'Cartão de Crédito';
      case 'tb':
        return 'Transferência Bancária';
      default:
        return $metodo;
    }
  }

  useEffect(() => {
    fetchReserva();
  }, [referencia, token]);

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

  const parsedJsonData = useMemo((): JsonData | null => {
    if (!reservaData?.jsonData) return null;
    try {
      return typeof reservaData.jsonData === 'string'
        ? (JSON.parse(reservaData.jsonData) as JsonData)
        : reservaData.jsonData;
    } catch {
      return null;
    }
  }, [reservaData?.jsonData]);

  const hotelInfo = parsedJsonData?.hotel || [];
  const extrasData = parsedJsonData?.extras ?? parsedJsonData?.extra ?? [];
  const voosData = parsedJsonData?.voo;

  const getVoosFromLeg = (leg?: VooDirection): (Escala | VooSegment)[] => {
    if (!leg) return [];
    if (Array.isArray(leg)) return leg;
    return leg.infoEscalas ?? [];
  };

  const voosIda = getVoosFromLeg(voosData?.departure);
  const voosVolta = getVoosFromLeg(voosData?.arrival);

  const buildQuartosPassageiros = (data: ReservaData) => {
    const partes: string[] = [];
    if (data.quartos) partes.push(`${data.quartos} Quartos`);
    if (data.adultos) partes.push(`${data.adultos} Adultos`);
    if (data.criancas && data.criancas !== '0') partes.push(`${data.criancas} Crianças`);
    return partes.length ? partes.join(' · ') : `${data.pessoas} Passageiros`;
  };

  const statusCode = String(reservaData?.status ?? '');

  return (
    <View style={styles.container}>
      <Stack.Screen
        options={{
          headerShown: true,
          headerTitleAlign: 'center',
          headerBackButtonDisplayMode: 'minimal',
          headerShadowVisible: false,
          headerStyle: { backgroundColor: '#F4F7FE' },
          headerTitle: () => (
            <Image
              source={require('@/assets/icons/logotipo-azul.png')}
              style={styles.logo}
              resizeMode="contain"
            />
          ),
        }}
      />

      {isLoading ? (
        <View style={styles.centered}>
          <LoadingSpinner size="large" />
        </View>
      ) : (
        <ScrollView
          showsVerticalScrollIndicator={false}
          contentContainerStyle={styles.content}
          refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}>
          {!!error && <Text style={styles.errorText}>{error}</Text>}

          {reservaData && (
            <>
              {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.destination}>{reservaData.destino}</Text>

              <Section>
                {!!reservaData.imagemCidade && (
                  <Image
                    source={{ uri: getImageUrl(reservaData.imagemCidade) }}
                    style={styles.summaryImage}
                  />
                )}
                <View style={styles.rowBetween}>
                  <View style={styles.idBlock}>
                    <Text style={styles.idTop}>ID #{reservaData.referenciaViagem}</Text>
                    <Text style={styles.fieldLabel}>Ref. da Reserva</Text>
                  </View>
                  <StatusBadge statusCode={statusCode} />
                </View>
                <DashedDivider width={0.5} borderStyle="solid" />
                <View>
                  <Text style={styles.idTop}>{reservaData.localizador || '---'}</Text>
                  <Text style={styles.fieldLabel}>Ref. do Operador</Text>
                </View>
              </Section>

              <Section title="Resumo da Reserva">
                <DashedDivider width={1} borderStyle="dashed" />
                <View style={styles.rowLineNoBorder}>
                  <Text style={styles.rowLabel}>Destino</Text>
                  <Text style={styles.rowValue}>{reservaData.destino}</Text>
                </View>
                <DashedDivider width={1} borderStyle="dashed" />
                <View style={styles.rowLineNoBorder}>
                  <Text style={styles.rowLabel}>Data Viagem</Text>
                  <Text style={styles.rowValue}>
                    {formatDateLong(reservaData.startDate)} -{' '}
                    {formatDateLong(reservaData.endDate)}
                  </Text>
                </View>
                <DashedDivider width={1} borderStyle="dashed" />
                <View style={styles.rowLineNoBorder}>
                  <Text style={styles.rowLabel}>Nr. de Noites</Text>
                  <Text style={styles.rowValue}>{reservaData.noites} noites</Text>
                </View>
                <DashedDivider width={1} borderStyle="dashed" />
                <View style={styles.rowLineNoBorder}>
                  <Text style={styles.rowLabel}>Quartos e Passageiros</Text>
                  <Text style={styles.rowValue}>{buildQuartosPassageiros(reservaData)}</Text>
                </View>
                <DashedDivider width={1} borderStyle="dashed" />
                <View style={styles.rowLineNoBorder}>
                  <Text style={styles.rowLabel}>Operador</Text>
                  <Text style={styles.rowValue}>{reservaData.operador || '---'}</Text>
                </View>
                <DashedDivider width={1} borderStyle="dashed" />
              </Section>

              <Section title="Alojamento">
                {hotelInfo.length > 0 ? (
                  hotelInfo.map((hotel, idx) => (
                    <HotelCard
                      key={`hotel-${hotel.id_hotel}-${idx}`}
                      hotel={hotel}
                      isFirst={idx === 0}
                    />
                  ))
                ) : (
                  <Text style={styles.empty}>Sem dados de alojamento.</Text>
                )}
              </Section>

              <Section title="Voos">
                {voosIda.length > 0 || voosVolta.length > 0 ? (
                  <View style={styles.vooList}>
                    {voosIda.length > 0 && (
                      <VooCard segmentos={voosIda} tipo="ida" />
                    )}
                    {voosVolta.length > 0 && (
                      <VooCard segmentos={voosVolta} tipo="volta" />
                    )}
                  </View>
                ) : (
                  <Text style={styles.empty}>Sem dados de voos.</Text>
                )}
              </Section>

              <Section title="Passageiros">
                <DashedDivider width={1} borderStyle="dashed" />
                {reservaData.passageiros && reservaData.passageiros.length > 0 ? (
                  reservaData.passageiros.map((passageiro, idx) => (
                    <PassageiroCard
                      key={`passageiro-${idx}`}
                      passageiro={passageiro}
                      index={idx}
                      isFirst={idx === 0}
                      isOpen={expandedPassageiros.has(idx)}
                      onToggle={() => togglePassageiro(idx)}
                    />
                  ))
                ) : (
                  <Text style={styles.empty}>Sem passageiros associados.</Text>
                )}
              </Section>

              <Section title="Extras">
                {extrasData.length > 0 ? (
                  <View style={styles.extrasList}>
                    {extrasData.map((extra) => (
                      <View style={styles.extrasItem} key={extra.name}>
                        <Text style={styles.extrasItemText}>{extra.name}</Text>
                      </View>
                    ))}
                  </View>
                ) : (
                  <Text style={styles.empty}>Sem extras associados.</Text>
                )}
              </Section>

              <Section title="Histórico de Pagamentos">
                {pagamentos.length > 0 ? (
                  <>
                    <View style={styles.tableHeader}>
                      <View style={styles.tableCellLeft}>
                        <Text style={styles.tableHeaderText}>Data</Text>
                      </View>
                      <View style={styles.tableCellMid}>
                        <Text style={styles.tableHeaderText}>Valor</Text>
                      </View>
                      <View style={styles.tableCellRight}>
                        <Text style={styles.tableHeaderText}>Meio Pag.</Text>
                      </View>
                    </View>
                    <DashedDivider width={1} borderStyle="dashed" />
                    {pagamentos.map((pagamento, idx) => (
                      <React.Fragment key={`pagamento-${idx}`}>
                        <View
                          style={[
                            styles.tableRow,
                            idx === pagamentos.length - 1 && styles.tableRowLast,
                          ]}>
                          <View style={styles.tableCellLeft}>
                            <Text style={styles.tableValueText}>
                              {formatDateShort(pagamento.data_pagamento || pagamento.data_hora)}
                            </Text>
                          </View>
                          <View style={styles.tableCellMid}>
                            <Text style={styles.tableValueText}>
                              {formatCurrency(pagamento.valor)}
                            </Text>
                          </View>
                          <View style={styles.tableCellRight}>
                            <Text style={styles.tableValueText}>{metodosPagamento(pagamento.metodoPagamento)}</Text>
                          </View>
                        </View>
                        <DashedDivider width={1} borderStyle="dashed" />
                      </React.Fragment>
                    ))}
                  </>
                ) : (
                  <Text style={styles.empty}>Sem pagamentos registados.</Text>
                )}
              </Section>

              <ValorReservaCard reserva={reservaData} />

              <Section title="Documentos">
                <DashedDivider width={1} borderStyle="dashed" />
                {documentos.length > 0 ? (
                  documentos.map((documento, idx) => (
                    <React.Fragment key={`documento-${idx}`}>
                      <DocumentoRow
                        documento={documento}
                        isLast={idx === documentos.length - 1}
                      />
                      <DashedDivider width={1} borderStyle="dashed" />
                    </React.Fragment>
                  ))
                ) : (
                  <Text style={styles.empty}>Sem documentos associados.</Text>
                )}
              </Section>

              {!!cachedAt && (
                <Text style={styles.syncLabel}>
                  Atualizado em: {new Date(cachedAt).toLocaleDateString('pt-PT', {
                    day: '2-digit',
                    month: '2-digit',
                    year: 'numeric',
                    hour: '2-digit',
                    minute: '2-digit',
                  })}
                </Text>
              )}
            </>
          )}
        </ScrollView>
      )}
    </View>
  );
}
