import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
import { colors } from '@/assets/styles/colors';
import styles from '@/styles/screens/tabs/contactos.styles';
import { FontAwesome } from '@expo/vector-icons';
import Constants, { ExecutionEnvironment } from 'expo-constants';
import { lazy, Suspense, useMemo, useState } from 'react';
import { Image, Platform, Pressable, Text, View } from 'react-native';

const MAP_ZOOM = 15;
const isExpoGo = Constants.executionEnvironment === ExecutionEnvironment.StoreClient;
const useNativeMaps = !isExpoGo && (Platform.OS === 'ios' || Platform.OS === 'android');

const NativeMapPreview = useNativeMaps
  ? lazy(() => import('./ContactMapPreviewNative'))
  : null;

const buildStaticMapUrl = (lat: number, lng: number): string => {
  const delta = 0.012;
  const bbox = [lng - delta, lat - delta, lng + delta, lat + delta].join(',');
  return `https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/export?bbox=${bbox}&bboxSR=4326&size=600,300&format=png&f=image`;
};

type Props = {
  lat: number;
  lng: number;
  title?: string;
  onPress: () => void;
};

function StaticMapFallback({ lat, lng, onPress }: Props) {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const mapUrl = useMemo(() => buildStaticMapUrl(lat, lng), [lat, lng]);

  return (
    <Pressable onPress={onPress} style={styles.mapImageWrap}>
      <Image
        source={{ uri: mapUrl }}
        style={styles.mapImage}
        resizeMode="cover"
        onLoadStart={() => {
          setLoading(true);
          setError(false);
        }}
        onLoad={() => setLoading(false)}
        onError={() => {
          setLoading(false);
          setError(true);
        }}
      />
      {loading && !error && (
        <View style={styles.mapOverlay}>
          <LoadingSpinner size="small" />
        </View>
      )}
      {error && (
        <View style={styles.mapOverlay}>
          <FontAwesome name="map-marker" size={28} color={colors.vermelho} />
          <Text style={styles.mapErrorText}>Mapa indisponível</Text>
        </View>
      )}
    </Pressable>
  );
}

export function ContactMapPreview(props: Props) {
  if (NativeMapPreview) {
    return (
      <Suspense fallback={<StaticMapFallback {...props} />}>
        <NativeMapPreview {...props} />
      </Suspense>
    );
  }

  return <StaticMapFallback {...props} />;
}
