import { NativeStackScreenProps } from '@react-navigation/native-stack';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  RefreshControl,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import * as api from '../api/endpoints';
import { Project } from '../api/types';
import { useSession } from '../auth/session';
import { getProjects, saveProjectList, saveTemplates, setActiveProjectId } from '../db/repositories';
import { isOnline } from '../net/connectivity';
import { runSync } from '../sync/engine';
import { RootStackParamList } from '../navigation/types';
import { COLORS, PrimaryButton } from '../ui/components';

type Props = NativeStackScreenProps<RootStackParamList, 'Projects'>;

/** Tolerante con la forma de la respuesta: `{projects}` (actual), `{data}` o array. */
function normalize(res: unknown): Project[] {
  if (Array.isArray(res)) return res as Project[];
  const obj = (res ?? {}) as { projects?: Project[]; data?: Project[] };
  return obj.projects ?? obj.data ?? [];
}

export function ProjectsScreen({ navigation }: Props) {
  const { user, signOut } = useSession();
  const [projects, setProjects] = useState<Project[]>([]);
  const [loading, setLoading] = useState(false);
  const [opening, setOpening] = useState<number | null>(null);
  const [showMenu, setShowMenu] = useState(false);
  const dropdownRef = useRef<View>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      if (await isOnline()) {
        const list = normalize(await api.listProjects());
        await saveProjectList(list);
        // Prefetch del catálogo global de plantillas: así quedan SIEMPRE en
        // local y se puede inspeccionar offline aunque el proyecto no se haya
        // abierto todavía. No bloquea la lista si /templates falla.
        try {
          const { templates } = await api.getTemplates();
          await saveTemplates(templates);
        } catch (e) {
          console.warn('No se pudieron prefetchar las plantillas:', e);
        }
      }
      setProjects(await getProjects());
    } catch (e) {
      console.warn('No se pudo refrescar /projects, usando datos locales:', e);
      setProjects(await getProjects()); // fallback offline
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  const openProject = useCallback(
    async (p: Project) => {
      setOpening(p.id);
      try {
        await setActiveProjectId(p.id);
        // runSync ya resuelve ambos casos: sin cursor baja el snapshot completo,
        // con cursor baja el delta (y vacía primero el outbox, vacío en la 1ª vez).
        if (await isOnline()) await runSync(p.id);
        navigation.navigate('ProjectDetail', { projectId: p.id, name: p.name });
      } finally {
        setOpening(null);
      }
    },
    [navigation],
  );

  const handleLogout = () => {
    setShowMenu(false);
    signOut();
  };

  const handleSettings = () => {
    setShowMenu(false);
    navigation.navigate('Settings');
  };

  return (
    <View style={styles.container}>
      {/* Header with dropdown menu */}
      <View style={styles.header}>
        <Text style={styles.headerTitle}>Proyectos</Text>
        <TouchableOpacity
          ref={dropdownRef}
          style={styles.dropdownWrapper}
          onPress={() => setShowMenu(!showMenu)}
          activeOpacity={1}
        >
          <Text style={styles.dropdownLabel}>
            {user?.name ?? 'Usuario'}
            <Text style={styles.chevron}> ▼</Text>
          </Text>
          {showMenu && (
            <View style={styles.dropdownMenu} pointerEvents="box-none">
              <TouchableOpacity style={styles.dropdownItem} onPress={handleSettings} activeOpacity={0.7}>
                <Text style={styles.dropdownItemText}>⚙ Configuración</Text>
              </TouchableOpacity>
              <TouchableOpacity style={[styles.dropdownItem, styles.dropdownItemDanger]} onPress={handleLogout} activeOpacity={0.7}>
                <Text style={styles.dropdownItemText}>Salir</Text>
              </TouchableOpacity>
            </View>
          )}
        </TouchableOpacity>
      </View>

      {/* Close dropdown when tapping outside */}
      <TouchableOpacity onPress={() => setShowMenu(false)} style={styles.touchOutside}>
        <FlatList
          data={projects}
          keyExtractor={(p) => String(p.id)}
          refreshControl={<RefreshControl refreshing={loading} onRefresh={load} />}
          ListEmptyComponent={loading ? null : <Text style={styles.empty}>No hay proyectos.</Text>}
          renderItem={({ item }) => (
            <TouchableOpacity style={styles.card} onPress={() => openProject(item)} activeOpacity={0.7}>
              <View style={styles.cardContent}>
                <Text style={styles.cardName}>{item.name}</Text>
                {item.reference ? <Text style={styles.cardMeta}>Ref: {item.reference}</Text> : null}
                {item.address ? <Text style={styles.cardMeta}>📍 {item.address}</Text> : null}
                {item.status ? <Text style={styles.cardMeta}>Estado: {item.status}</Text> : null}
              </View>
              {opening === item.id ? (
                <ActivityIndicator />
              ) : (
                <Text style={styles.chevron}>›</Text>
              )}
            </TouchableOpacity>
          )}
        />
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: 16,
  },
  headerTitle: { fontSize: 20, fontWeight: '700', color: COLORS.primary },
  dropdownWrapper: {
    position: 'relative',
  },
  dropdownLabel: {
    fontSize: 16,
    fontWeight: '600',
    color: '#333',
  },
  chevron: { fontSize: 14, color: '#666' },
  dropdownMenu: {
    position: 'absolute',
    top: 40,
    right: 0,
    backgroundColor: '#fff',
    borderRadius: 8,
    borderWidth: 1,
    borderColor: COLORS.border,
    overflow: 'hidden',
    minWidth: 180,
    elevation: 4,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    zIndex: 100,
  },
  dropdownItem: {
    paddingHorizontal: 16,
    paddingVertical: 12,
  },
  dropdownItemDanger: {
    borderTopWidth: StyleSheet.hairlineWidth,
    borderTopColor: COLORS.border,
  },
  dropdownItemText: {
    fontSize: 15,
    color: '#333',
  },
  touchOutside: {
    flex: 1,
  },
  card: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 16,
    paddingVertical: 16,
    borderTopWidth: StyleSheet.hairlineWidth,
    borderColor: COLORS.border,
    backgroundColor: '#fff',
  },
  cardContent: { flex: 1 },
  cardName: { fontSize: 16, fontWeight: '600', color: '#111' },
  cardMeta: { fontSize: 13, color: COLORS.muted, marginTop: 4 },
  empty: { textAlign: 'center', marginTop: 40, color: '#888' },
});
