import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import MapView, { Marker, UrlTile, PROVIDER_DEFAULT } from 'react-native-maps';
import { Contact } from '@/store/useContactStore';
import { getAllContactsForMap } from '@/lib/database';

// ── Status colour map ────────────────────────────────────────────────────────
const STATUS_COLORS: Record<string, string> = {
  Active: '#1A6B72',
  'Return Visit': '#E65100',
  'Bible Study': '#2E7D32',
  'Not Interested': '#6B7280',
  'Do Not Call': '#C62828',
};

const DEFAULT_PIN_COLOR = '#1A6B72';

// ── Cluster helpers (manual — no external package required) ──────────────────
const CLUSTER_THRESHOLD = 0.0005; // ~55 m

interface ClusterGroup {
  key: string;
  latitude: number;
  longitude: number;
  contacts: Contact[];
}

function clusterContacts(contacts: Contact[]): ClusterGroup[] {
  const groups: ClusterGroup[] = [];
  const assigned = new Set<string>();

  for (const c of contacts) {
    if (assigned.has(c.id) || c.latitude == null || c.longitude == null) continue;
    const group: Contact[] = [c];
    assigned.add(c.id);

    for (const other of contacts) {
      if (assigned.has(other.id) || other.latitude == null || other.longitude == null) continue;
      const dLat = Math.abs((c.latitude ?? 0) - (other.latitude ?? 0));
      const dLng = Math.abs((c.longitude ?? 0) - (other.longitude ?? 0));
      if (dLat < CLUSTER_THRESHOLD && dLng < CLUSTER_THRESHOLD) {
        group.push(other);
        assigned.add(other.id);
      }
    }

    groups.push({
      key: c.id,
      latitude: c.latitude ?? 0,
      longitude: c.longitude ?? 0,
      contacts: group,
    });
  }
  return groups;
}

// ── Mini contact card ────────────────────────────────────────────────────────
interface MiniCardProps {
  contact: Contact;
  onClose: () => void;
  onViewFull: (id: string) => void;
}

function MiniCard({ contact, onClose, onViewFull }: MiniCardProps) {
  const pinColor = STATUS_COLORS[contact.status] ?? DEFAULT_PIN_COLOR;
  return (
    <View style={styles.miniCard}>
      <View style={styles.miniCardRow}>
        <View style={{ flex: 1 }}>
          <Text style={styles.miniCardName} numberOfLines={1}>
            {contact.fullName}
          </Text>
          {contact.territoryCode ? (
            <Text style={styles.miniCardSub}>Territory: {contact.territoryCode}</Text>
          ) : null}
          <Text style={styles.miniCardSub}>Last visit: —</Text>
        </View>
        <View>
          <View style={[styles.statusBadge, { backgroundColor: pinColor }]}>
            <Text style={styles.statusBadgeText}>{contact.status}</Text>
          </View>
        </View>
      </View>
      <View style={styles.miniCardActions}>
        <TouchableOpacity
          style={styles.viewBtn}
          onPress={() => onViewFull(contact.id)}
        >
          <Text style={styles.viewBtnText}>View Full Record →</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.closeBtn} onPress={onClose}>
          <Text style={styles.closeBtnText}>✕</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

// ── No-GPS row ───────────────────────────────────────────────────────────────
interface NoGpsRowProps {
  contact: Contact;
  onPress: (id: string) => void;
}

function NoGpsRow({ contact, onPress }: NoGpsRowProps) {
  const initials = contact.fullName
    .split(' ')
    .map((w) => w[0])
    .join('')
    .toUpperCase()
    .slice(0, 2);
  const pinColor = STATUS_COLORS[contact.status] ?? DEFAULT_PIN_COLOR;
  return (
    <TouchableOpacity style={styles.noGpsRow} onPress={() => onPress(contact.id)}>
      <View style={[styles.avatar, { backgroundColor: pinColor }]}>
        <Text style={styles.avatarText}>{initials}</Text>
      </View>
      <View style={{ flex: 1 }}>
        <Text style={styles.noGpsName} numberOfLines={1}>
          {contact.fullName}
        </Text>
        <Text style={styles.noGpsSub}>
          {contact.status}
          {contact.territoryCode ? ` — ${contact.territoryCode}` : ''}
        </Text>
      </View>
      <Text style={styles.noGpsChevron}>›</Text>
    </TouchableOpacity>
  );
}

// ── Main Screen ──────────────────────────────────────────────────────────────
export default function MapScreen() {
  const router = useRouter();
  const mapRef = useRef<MapView>(null);

  const [contacts, setContacts] = useState<Contact[]>([]);
  const [loading, setLoading] = useState(true);
  const [territories, setTerritories] = useState<string[]>([]);
  const [selectedTerritory, setSelectedTerritory] = useState<string>('All');
  const [selectedContact, setSelectedContact] = useState<Contact | null>(null);

  // Load on mount
  useEffect(() => {
    (async () => {
      try {
        const all = await getAllContactsForMap();
        setContacts(all);

        // Unique territory codes from GPS contacts
        const codes = Array.from(
          new Set(
            all
              .filter((c) => c.latitude != null && c.longitude != null && c.territoryCode)
              .map((c) => c.territoryCode as string)
          )
        ).sort();
        setTerritories(codes);
      } catch (e) {
        console.error('Map load error', e);
      } finally {
        setLoading(false);
      }
    })();
  }, []);

  // Derived lists
  const gpsContacts = contacts.filter((c) => c.latitude != null && c.longitude != null);
  const noGpsContacts = contacts.filter((c) => c.latitude == null || c.longitude == null);

  const filteredGps =
    selectedTerritory === 'All'
      ? gpsContacts
      : gpsContacts.filter((c) => c.territoryCode === selectedTerritory);

  const clusters = clusterContacts(filteredGps);

  // Auto-zoom when contacts load
  useEffect(() => {
    if (filteredGps.length === 0 || !mapRef.current) return;
    const coords = filteredGps.map((c) => ({
      latitude: c.latitude as number,
      longitude: c.longitude as number,
    }));
    setTimeout(() => {
      mapRef.current?.fitToCoordinates(coords, {
        edgePadding: { top: 80, right: 40, bottom: 300, left: 40 },
        animated: true,
      });
    }, 600);
  }, [filteredGps.length, selectedTerritory]);

  const handlePinPress = useCallback((contact: Contact) => {
    setSelectedContact(contact);
  }, []);

  const handleViewFull = useCallback(
    (id: string) => {
      setSelectedContact(null);
      router.push(`/contact/${id}` as any);
    },
    [router]
  );

  const handleNoGpsPress = useCallback(
    (id: string) => {
      router.push(`/contact/${id}` as any);
    },
    [router]
  );

  if (loading) {
    return (
      <SafeAreaView style={styles.loadingContainer}>
        <ActivityIndicator size="large" color="#1A6B72" />
        <Text style={styles.loadingText}>Loading map…</Text>
      </SafeAreaView>
    );
  }

  return (
    <SafeAreaView style={styles.container} edges={['top']}>
      {/* ── Territory filter chips ── */}
      <View style={styles.chipBar}>
        <ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={styles.chipScroll}
        >
          {['All', ...territories].map((t) => {
            const active = selectedTerritory === t;
            return (
              <Pressable
                key={t}
                style={[styles.chip, active && styles.chipActive]}
                onPress={() => {
                  setSelectedTerritory(t);
                  setSelectedContact(null);
                }}
              >
                <Text style={[styles.chipText, active && styles.chipTextActive]}>{t}</Text>
              </Pressable>
            );
          })}
        </ScrollView>
      </View>

      {/* ── Map ── */}
      <View style={styles.mapContainer}>
        <MapView
          ref={mapRef}
          provider={PROVIDER_DEFAULT}
          mapType="none"
          style={StyleSheet.absoluteFillObject}
          initialRegion={{
            latitude: 14.5995,
            longitude: 120.9842,
            latitudeDelta: 0.05,
            longitudeDelta: 0.05,
          }}
          onPress={() => setSelectedContact(null)}
        >
          <UrlTile
            urlTemplate="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
            maximumZ={19}
            flipY={false}
          />

          {clusters.map((group) => {
            const isCluster = group.contacts.length > 1;
            const rep = group.contacts[0];
            const pinColor = STATUS_COLORS[rep.status] ?? DEFAULT_PIN_COLOR;

            if (isCluster) {
              return (
                <Marker
                  key={group.key}
                  coordinate={{ latitude: group.latitude, longitude: group.longitude }}
                  onPress={() => handlePinPress(rep)}
                >
                  <View style={[styles.clusterMarker, { backgroundColor: pinColor }]}>
                    <Text style={styles.clusterCount}>{group.contacts.length}</Text>
                  </View>
                </Marker>
              );
            }

            return (
              <Marker
                key={group.key}
                coordinate={{ latitude: group.latitude, longitude: group.longitude }}
                pinColor={pinColor}
                title={rep.fullName}
                onPress={() => handlePinPress(rep)}
              />
            );
          })}
        </MapView>

        {/* Pin count badge */}
        <View style={styles.pinCountBadge}>
          <Text style={styles.pinCountText}>
            {filteredGps.length} pin{filteredGps.length !== 1 ? 's' : ''}
          </Text>
        </View>

        {/* Mini card overlay */}
        {selectedContact && (
          <MiniCard
            contact={selectedContact}
            onClose={() => setSelectedContact(null)}
            onViewFull={handleViewFull}
          />
        )}
      </View>

      {/* ── No GPS section ── */}
      {noGpsContacts.length > 0 && (
        <View style={styles.noGpsSection}>
          <View style={styles.noGpsHeader}>
            <View style={styles.noGpsDivider} />
            <Text style={styles.noGpsTitle}>
              {noGpsContacts.length} contact{noGpsContacts.length !== 1 ? 's' : ''} without GPS
            </Text>
            <View style={styles.noGpsDivider} />
          </View>
          <FlatList
            data={noGpsContacts}
            keyExtractor={(c) => c.id}
            renderItem={({ item }) => (
              <NoGpsRow contact={item} onPress={handleNoGpsPress} />
            )}
            style={styles.noGpsList}
            showsVerticalScrollIndicator={false}
          />
        </View>
      )}
    </SafeAreaView>
  );
}

// ── Styles ───────────────────────────────────────────────────────────────────
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F8F4EF',
  },
  loadingContainer: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#F8F4EF',
  },
  loadingText: {
    marginTop: 12,
    color: '#2C3E50',
    fontSize: 15,
  },

  // Chip bar
  chipBar: {
    backgroundColor: '#F8F4EF',
    paddingVertical: 8,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: '#D0CCC6',
  },
  chipScroll: {
    paddingHorizontal: 12,
    gap: 8,
  },
  chip: {
    paddingHorizontal: 14,
    paddingVertical: 6,
    borderRadius: 20,
    borderWidth: 1.5,
    borderColor: '#1A6B72',
    backgroundColor: 'transparent',
  },
  chipActive: {
    backgroundColor: '#1A6B72',
  },
  chipText: {
    fontSize: 13,
    fontWeight: '600',
    color: '#1A6B72',
  },
  chipTextActive: {
    color: '#fff',
  },

  // Map
  mapContainer: {
    flex: 1,
  },

  // Pin count badge
  pinCountBadge: {
    position: 'absolute',
    top: 10,
    right: 12,
    backgroundColor: 'rgba(26,107,114,0.88)',
    borderRadius: 12,
    paddingHorizontal: 10,
    paddingVertical: 4,
  },
  pinCountText: {
    color: '#fff',
    fontSize: 12,
    fontWeight: '700',
  },

  // Cluster marker
  clusterMarker: {
    minWidth: 36,
    minHeight: 36,
    borderRadius: 18,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 2,
    borderColor: '#fff',
    paddingHorizontal: 6,
  },
  clusterCount: {
    color: '#fff',
    fontWeight: '800',
    fontSize: 14,
  },

  // Mini card
  miniCard: {
    position: 'absolute',
    bottom: 16,
    left: 12,
    right: 12,
    backgroundColor: '#fff',
    borderRadius: 16,
    padding: 16,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.18,
    shadowRadius: 8,
    elevation: 8,
  },
  miniCardRow: {
    flexDirection: 'row',
    alignItems: 'flex-start',
    gap: 12,
    marginBottom: 12,
  },
  miniCardName: {
    fontSize: 17,
    fontWeight: '700',
    color: '#2C3E50',
    marginBottom: 2,
  },
  miniCardSub: {
    fontSize: 13,
    color: '#6B7280',
    marginTop: 1,
  },
  statusBadge: {
    borderRadius: 8,
    paddingHorizontal: 8,
    paddingVertical: 4,
    alignSelf: 'flex-start',
  },
  statusBadgeText: {
    color: '#fff',
    fontSize: 11,
    fontWeight: '700',
  },
  miniCardActions: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
  },
  viewBtn: {
    flex: 1,
    backgroundColor: '#1A6B72',
    borderRadius: 10,
    paddingVertical: 10,
    alignItems: 'center',
  },
  viewBtnText: {
    color: '#fff',
    fontWeight: '700',
    fontSize: 14,
  },
  closeBtn: {
    width: 40,
    height: 40,
    borderRadius: 20,
    backgroundColor: '#F3F4F6',
    alignItems: 'center',
    justifyContent: 'center',
  },
  closeBtnText: {
    fontSize: 16,
    color: '#6B7280',
    fontWeight: '700',
  },

  // No GPS section
  noGpsSection: {
    maxHeight: 220,
    backgroundColor: '#F8F4EF',
    borderTopWidth: StyleSheet.hairlineWidth,
    borderTopColor: '#D0CCC6',
  },
  noGpsHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 16,
    paddingVertical: 8,
    gap: 8,
  },
  noGpsDivider: {
    flex: 1,
    height: StyleSheet.hairlineWidth,
    backgroundColor: '#B0AAA4',
  },
  noGpsTitle: {
    fontSize: 12,
    fontWeight: '600',
    color: '#6B7280',
    textTransform: 'uppercase',
    letterSpacing: 0.5,
  },
  noGpsList: {
    flex: 1,
  },
  noGpsRow: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 16,
    paddingVertical: 10,
    gap: 12,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: '#E5E0DA',
  },
  avatar: {
    width: 36,
    height: 36,
    borderRadius: 18,
    alignItems: 'center',
    justifyContent: 'center',
  },
  avatarText: {
    color: '#fff',
    fontWeight: '800',
    fontSize: 14,
  },
  noGpsName: {
    fontSize: 14,
    fontWeight: '600',
    color: '#2C3E50',
  },
  noGpsSub: {
    fontSize: 12,
    color: '#6B7280',
    marginTop: 1,
  },
  noGpsChevron: {
    fontSize: 20,
    color: '#B0AAA4',
  },
});
