import { API_ENDPOINTS, buildApiUrl } from '@/assets/config/api';
import { useAuth } from '@/assets/contexts/useAuth';
import { cacheContacts, getCachedContacts } from '@/assets/services/offlineStorage';
import { colors } from '@/assets/styles/colors';
import { ContactData, ContactResponse, SocialMedia } from '@/assets/types';
import styles from '@/styles/screens/tabs/contactos.styles';
import { FontAwesome } from '@expo/vector-icons';
import * as Clipboard from 'expo-clipboard';
import { useEffect, useState } from 'react';
import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
import {
  Alert,
  Image,
  Linking,
  Pressable,
  RefreshControl,
  ScrollView,
  Text,
  View,
} from 'react-native';
// ─── helpers ──────────────────────────────────────────────────────────────────

const openPhone = (phone: string) => {
  const clean = phone.replace(/[^\d+]/g, '');
  Linking.openURL(`tel:${clean}`).catch(() =>
    Alert.alert('Erro', 'Não foi possível abrir a aplicação de telefone.')
  );
};

const openEmail = (email: string) => {
  Linking.openURL(`mailto:${email}`).catch(() =>
    Alert.alert('Erro', 'Não foi possível abrir a aplicação de e-mail.')
  );
};

const openWhatsApp = (value: string) => {
  const clean = value.replace(/[^\d+]/g, '');
  const url = `https://wa.me/${clean}`;
  Linking.openURL(url).catch(() =>
    Alert.alert('Erro', 'Não foi possível abrir o WhatsApp.')
  );
};

const openMaps = (address: string, lat?: number, lng?: number) => {
  const url =
    lat != null && lng != null
      ? `maps://?ll=${lat},${lng}&q=${encodeURIComponent(address)}`
      : `maps:?q=${encodeURIComponent(address)}`;

  Linking.openURL(url).catch(() =>
    Linking.openURL(
      lat != null && lng != null
        ? `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`
        : `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(address)}`
    ).catch(() => Alert.alert('Erro', 'Não foi possível abrir a aplicação de mapas.'))
  );
};

const copyToClipboard = async (value: string, label: string) => {
  await Clipboard.setStringAsync(value);
  Alert.alert('Copiado', `${label} copiado para a área de transferência.`);
};

const extractPhone = (url: string): string => {
  const match = url.match(/(?:phone=|wa\.me\/)([\d+]+)/);
  if (match) return `+${match[1].replace(/^\+/, '')}`;
  const clean = url.replace(/[^\d+]/g, '');
  return clean.startsWith('+') ? clean : `+${clean}`;
};

const parseCoords = (raw?: string | null): { lat: number; lng: number } | null => {
  if (!raw) return null;
  const parts = raw.split(',').map((s) => parseFloat(s.trim()));
  if (parts.length === 2 && !isNaN(parts[0]) && !isNaN(parts[1])) {
    return { lat: parts[0], lng: parts[1] };
  }
  return null;
};


const parseHorarios = (raw: string): { dia: string; horas: string }[] => {
  return raw
    .split('\n')
    .map((line) => line.trim())
    .filter(Boolean)
    .map((line) => {
      const sep = line.lastIndexOf(':');
      if (sep > 0) {
        return { dia: line.slice(0, sep).trim(), horas: line.slice(sep + 1).trim() };
      }
      const parts = line.split(/\s{2,}|\t/);
      if (parts.length >= 2) {
        return { dia: parts[0].trim(), horas: parts.slice(1).join(' ').trim() };
      }
      return { dia: line, horas: '' };
    });
};

const SOCIAL_ICONS: Record<string, string> = {
  facebook: 'facebook',
  instagram: 'instagram',
  tiktok: 'music', // FontAwesome doesn't have tiktok
  twitter: 'twitter',
  linkedin: 'linkedin',
  youtube: 'youtube-play',
};

// ─── screen ───────────────────────────────────────────────────────────────────

export default function Contactos() {
  const { token } = useAuth();
  const [contactData, setContactData] = useState<ContactData | null>(null);
  const [socials, setSocials] = useState<SocialMedia[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [mapLoading, setMapLoading] = useState(true);
  const [mapError, setMapError] = useState(false);

  const fetchContacts = async () => {
    // 1. Mostrar cache imediatamente enquanto atualiza em fundo
    const cached = await getCachedContacts();
    if (cached.contactData) {
      setContactData(cached.contactData);
      setSocials(cached.socials);
      setIsLoading(false);
    }

    try {
      const formData = new FormData();
      if (token) formData.append('token', token);

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

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

      console.log('data', data);

      if (data.status === 200 && data.contact) {
        const validSocials = (data.socials || []).filter((s) => s.value?.trim());
        setContactData(data.contact);
        setSocials(validSocials);
        setError(null);
        await cacheContacts(data.contact, validSocials);
      } else if (!cached.contactData) {
        setError(data.message || 'Não foi possível carregar os contactos.');
      }
    } catch {
      if (!cached.contactData) {
        setError('Sem ligação à internet e sem dados guardados.');
      }
    } finally {
      setIsLoading(false);
    }
  };

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

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

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

  if (error && !contactData) {
    return (
      <View style={styles.centered}>
        <Text style={styles.errorText}>{error}</Text>
      </View>
    );
  }

  const horarios = contactData?.horarios ? parseHorarios(contactData.horarios) : [];
  const coords = parseCoords(contactData?.coordenadas);
  const mapUrl = coords
    ? `https://staticmap.openstreetmap.de/staticmap.php?center=${coords.lat},${coords.lng}&zoom=15&size=600x300&markers=${coords.lat},${coords.lng},red-pushpin`
    : null;

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

        <Text style={styles.pageTitle}>Contactos Agência</Text>

        {/* ── Ações rápidas ── */}
        <View style={styles.actionsRow}>
          {!!contactData?.mobilePhone && (
            <Pressable
              style={styles.actionBtn}
              onPress={() => openPhone(contactData.telephone)}>
              <View style={styles.actionIconWrap}>
                <Image source={require('@/assets/icons/telefone.png')} style={styles.actionIcon} />
              </View>
              <Text style={styles.actionLabel}>Ligar Agora</Text>
              <Text style={styles.actionSub} numberOfLines={1}>
                {contactData.telephone}
              </Text>
            </Pressable>
          )}

          {!!contactData?.email && (
            <Pressable
              style={styles.actionBtn}
              onPress={() => openEmail(contactData.email)}>
              <View style={styles.actionIconWrap}>
                <Image source={require('@/assets/icons/email.png')} style={styles.actionIcon} />
              </View>
              <Text style={styles.actionLabel}>Enviar Email</Text>
              <Text style={styles.actionSub} numberOfLines={1}>
                {contactData.email}
              </Text>
            </Pressable>
          )}

          {!!contactData?.mobilePhone && (
            <Pressable
              style={styles.actionBtn}
              onPress={() => openWhatsApp(contactData.mobilePhone!)}>
              <View style={styles.actionIconWrap}>
                <Image source={require('@/assets/icons/whatsapp.png')} style={styles.actionIcon} />
              </View>
              <Text style={styles.actionLabel}>Falar no Chat</Text>
              <Text style={styles.actionSub} numberOfLines={1}>
                {extractPhone(contactData.mobilePhone)}
              </Text>
            </Pressable>
          )}
        </View>

        {/* ── Localização ── */}
        {!!contactData?.address && (
          <View style={styles.card}>
            <Text style={styles.cardTitle}>Localização</Text>

            {!!mapUrl && (
              <Pressable
                onPress={() => openMaps(contactData.address, coords?.lat, coords?.lng)}
                style={styles.mapImageWrap}>
                <Image
                  source={{ uri: mapUrl }}
                  style={styles.mapImage}
                  resizeMode="cover"
                  onLoadStart={() => { setMapLoading(true); setMapError(false); }}
                  onLoad={() => setMapLoading(false)}
                  onError={() => { setMapLoading(false); setMapError(true); }}
                />
                {mapLoading && !mapError && (
                  <View style={styles.mapOverlay}>
                    <LoadingSpinner size="small" />
                  </View>
                )}
                {mapError && (
                  <View style={styles.mapOverlay}>
                    <FontAwesome name="map-marker" size={28} color={colors.vermelho} />
                    <Text style={styles.mapErrorText}>Mapa indisponível</Text>
                  </View>
                )}
              </Pressable>
            )}

            <View style={styles.addressRow}>
              <FontAwesome name="map-marker" size={16} color={colors.vermelho} />
              <Text style={styles.addressText}>{contactData.address}</Text>
              <Pressable onPress={() => copyToClipboard(contactData.address, 'Morada')}>
                <FontAwesome name="copy" size={14} color={colors.azul} style={styles.copyIcon} />
              </Pressable>
            </View>
            <Pressable
              style={styles.direcoeBtn}
              onPress={() => openMaps(contactData.address, coords?.lat, coords?.lng)}>
              <Text style={styles.direcoeBtnText}>Obter Direções</Text>
              <Image source={require('@/assets/icons/seta-up.png')} style={styles.saveButtonIcon} />
              </Pressable>
          </View>
        )}

        {/* ── Horário de Funcionamento ── */}
        {horarios.length > 0 && (
          <View style={styles.card}>
            <Text style={styles.cardTitle}>Horário de Funcionamento</Text>
            {horarios.map((item, idx) => (
              <View
                key={idx}
                style={[styles.horarioRow, idx < horarios.length - 1 && styles.horarioRowBorder]}>
                <Text style={styles.horarioDia}>{item.dia}</Text>
                <Text style={[
                  styles.horarioHoras,
                  item.horas.toLowerCase() === 'fechado' && styles.horarioFechado,
                ]}>
                  {item.horas || '—'}
                </Text>
              </View>
            ))}
          </View>
        )}
        
        {/* ── Redes Sociais ── */}
        {socials.length > 0 && (
          <View style={styles.card}>
            <Text style={styles.cardTitle}>Redes Sociais</Text>
            <View style={styles.socialsRow}>
              {socials.map((social, idx) => (
                <Pressable
                  key={idx}
                  style={styles.socialBtn}
                  onPress={() => Linking.openURL(social.value).catch(() => null)}>
                  <FontAwesome
                    name={(SOCIAL_ICONS[social.key.toLowerCase()] ?? 'globe') as any}
                    size={20}
                    color={colors.azul}
                  />
                </Pressable>
              ))}
            </View>
          </View>
        )}
      </ScrollView>
    </View>
  );
}
