/**
 * Projekt-Übersicht + Switcher.
 *
 * Modal-Komponente die:
 *  - Den aktuellen Projekt-Status zeigt (Hauptchat oder konkretes Projekt)
 *  - Die Projekt-Liste rendert (sortiert nach letzter Aktivität)
 *  - Per Tap zwischen Projekten wechseln lässt
 *  - Neue Projekte anlegen kann
 *  - Bestehende editieren/beenden/archivieren
 *
 * Eingesetzt von ChatScreen (über den Projekt-Indicator) und von
 * SettingsScreen.tsx in der Section 'projects'.
 */

import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  FlatList,
  Modal,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';

import brainApi, { Project } from '../services/brainApi';
import rvs from '../services/rvs';

interface Props {
  /** Optional — wenn als Modal genutzt, sonst inline */
  visible?: boolean;
  onClose?: () => void;
  /** Wird gerufen wenn Stefan ein anderes Projekt fokussiert (App-lokale
   *  UI-Entscheidung, wechselt den Chat-Focus). */
  onActiveChanged?: (project: Project | null) => void;
  /** Der aktuell in der App fokussierte Kontext (App-lokale Source-of-Truth).
   *  Leer = Hauptchat. Steuert das ✓-FOCUS-Highlight. WICHTIG: der Drawer darf
   *  den Focus NICHT aus dem Brain-Status ableiten — im Multi-Threading gibt es
   *  kein globales active_project mehr (status.active ist null), das wuerde den
   *  Focus bei jedem Drawer-Oeffnen auf Hauptchat zuruecksetzen. */
  currentFocusId?: string;
  /** Queue-Status pro Kontext (key "__main__" = Hauptchat, sonst project_id).
   *  Wenn geliefert: Status-Dot pro Zeile gerendert. */
  queueStatus?: Record<string, { busy: boolean; queue_size: number }>;
}

function _fmtRel(unixSec: number): string {
  if (!unixSec) return '?';
  const diff = (Date.now() / 1000) - unixSec;
  if (diff < 60) return 'gerade eben';
  if (diff < 3600) return `vor ${Math.floor(diff / 60)} Min`;
  if (diff < 86400) return `vor ${Math.floor(diff / 3600)} Std`;
  if (diff < 86400 * 14) return `vor ${Math.floor(diff / 86400)} Tagen`;
  return new Date(unixSec * 1000).toLocaleDateString('de-DE');
}

export const ProjectsBrowser: React.FC<Props> = ({ visible = true, onClose, onActiveChanged, currentFocusId, queueStatus }) => {
  const _statusDot = (pid: string) => {
    const s = queueStatus?.[pid];
    if (!s) return { color: '#555570', label: '' };
    if (s.busy) return { color: '#FF6E6E', label: 'arbeitet' };
    if (s.queue_size > 0) return { color: '#FFD60A', label: `Queue: ${s.queue_size}` };
    return { color: '#34C759', label: 'idle' };
  };
  const [projects, setProjects] = useState<Project[]>([]);
  const [activeId, setActiveId] = useState<string>('');
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState<string | null>(null);
  const [newOpen, setNewOpen] = useState(false);
  const [newName, setNewName] = useState('');
  const [newDesc, setNewDesc] = useState('');
  const [editing, setEditing] = useState<Project | null>(null);
  const [editName, setEditName] = useState('');
  const [editDesc, setEditDesc] = useState('');

  // Refs damit useCallback NICHT bei jeder Re-Render des Parents neu erzeugt
  // wird (parent uebergibt oft inline-arrow-Callbacks, neue Identity jedes
  // Render → useCallback re-runs → useEffect refeuert → infinite spinner).
  const onActiveChangedRef = useRef(onActiveChanged);
  useEffect(() => { onActiveChangedRef.current = onActiveChanged; }, [onActiveChanged]);

  const load = useCallback(() => {
    setLoading(true); setErr(null);
    brainApi.getProjectStatus()
      .then(status => {
        // NUR die Projektliste + Queue uebernehmen. NICHT status.active in den
        // App-Focus pushen — im Multi-Threading ist das Brain-active_project
        // bedeutungslos (null), das wuerde den Focus bei jedem Drawer-Oeffnen
        // auf Hauptchat zuruecksetzen und alle Nachrichten dort landen lassen.
        setProjects(status.projects || []);
      })
      .catch(e => setErr(String(e?.message || e)))
      .finally(() => setLoading(false));
  }, []);

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

  // Highlight („✓ FOCUS") folgt dem App-Focus (Source-of-Truth), nicht dem
  // Brain. switchTo setzt activeId zusaetzlich sofort fuer Instant-Feedback.
  useEffect(() => { setActiveId(currentFocusId || ''); }, [currentFocusId]);

  // Reload bei RVS-Reconnect — sonst zeigt die Liste den Fast-Fail ewig
  useEffect(() => {
    if (!visible) return;
    const unsub = rvs.onStateChange((state) => { if (state === 'connected') load(); });
    return () => unsub();
  }, [visible, load]);

  const switchTo = useCallback((id: string) => {
    // Multi-Threading: Focus-Wechsel ist reine App-lokale UI-Entscheidung.
    // Brain wird nicht mehr benachrichtigt (kein globaler active_project mehr).
    // Wir suchen das Projekt lokal aus der Liste, damit die App den Namen kennt.
    setActiveId(id);
    const p = id ? (projects.find(x => x.id === id) || null) : null;
    onActiveChangedRef.current?.(p);
    if (onClose) onClose();
  }, [projects, onClose]);

  const createProject = useCallback(() => {
    const name = newName.trim();
    if (!name) return;
    brainApi.createProject({ name, description: newDesc.trim() })
      .then(() => {
        setNewName(''); setNewDesc(''); setNewOpen(false);
        load();
      })
      .catch(e => Alert.alert('Anlegen fehlgeschlagen', String(e?.message || e)));
  }, [newName, newDesc, load]);

  const openEdit = useCallback((p: Project) => {
    setEditing(p);
    setEditName(p.name);
    setEditDesc(p.description || '');
  }, []);

  const saveEdit = useCallback(() => {
    if (!editing) return;
    const patch: Partial<Pick<Project, 'name' | 'description'>> = {};
    if (editName.trim() && editName.trim() !== editing.name) patch.name = editName.trim();
    if (editDesc.trim() !== (editing.description || '')) patch.description = editDesc.trim();
    if (Object.keys(patch).length === 0) { setEditing(null); return; }
    brainApi.updateProject(editing.id, patch)
      .then(() => { setEditing(null); load(); })
      .catch(e => Alert.alert('Fehler', String(e?.message || e)));
  }, [editing, editName, editDesc, load]);

  const endProject = useCallback((p: Project) => {
    Alert.alert(`"${p.name}" beenden?`,
      'Bleibt sichtbar, kann nicht mehr aktiv sein außer mit explizitem Wiedereintritt.',
      [
        { text: 'Abbrechen', style: 'cancel' },
        { text: 'Beenden', onPress: () => {
          brainApi.endProject(p.id).then(() => load()).catch(e => Alert.alert('Fehler', String(e?.message || e)));
        }},
      ]);
  }, [load]);

  const archiveProject = useCallback((p: Project) => {
    Alert.alert(`"${p.name}" archivieren?`,
      'Verschwindet aus der Standardliste. Über "archivierte zeigen" erreichbar.',
      [
        { text: 'Abbrechen', style: 'cancel' },
        { text: 'Archivieren', style: 'destructive', onPress: () => {
          brainApi.archiveProject(p.id)
            .then(() => { setEditing(null); load(); })
            .catch(e => Alert.alert('Fehler', String(e?.message || e)));
        }},
      ]);
  }, [load]);

  // ── Render ────────────────────────────────────────────────

  const renderItem = ({ item }: { item: Project }) => {
    const isActive = item.id === activeId;
    const dot = _statusDot(item.id);
    return (
      <TouchableOpacity
        onPress={() => switchTo(item.id)}
        onLongPress={() => openEdit(item)}
        style={[s.row, isActive && s.rowActive]}
      >
        <View style={{ flex: 1 }}>
          <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
            {queueStatus && (
              <View style={{ width: 8, height: 8, borderRadius: 4, backgroundColor: dot.color }} />
            )}
            <Text style={[s.rowName, isActive && { color: '#34C759' }]}>{item.name}</Text>
            {item.status === 'ended' && <Text style={s.statusBadge}>beendet</Text>}
            {isActive && <Text style={s.activeBadge}>✓ FOCUS</Text>}
          </View>
          {item.description ? (
            <Text style={s.rowDesc} numberOfLines={2}>{item.description}</Text>
          ) : null}
          <Text style={s.rowMeta}>
            {item.turn_count} Turns · zuletzt {_fmtRel(item.last_activity_at)}
            {dot.label ? ` · ${dot.label}` : ''}
          </Text>
        </View>
      </TouchableOpacity>
    );
  };

  const body = (
    <View style={{ flex: 1, backgroundColor: '#0A0A14' }}>
      {/* Header */}
      <View style={s.header}>
        {onClose && (
          <TouchableOpacity onPress={onClose} style={s.headerBtn}>
            <Text style={s.headerBtnText}>‹</Text>
          </TouchableOpacity>
        )}
        <Text style={s.headerTitle}>Projekte</Text>
        <TouchableOpacity onPress={() => setNewOpen(true)} style={s.headerBtn}>
          <Text style={[s.headerBtnText, { color: '#34C759' }]}>+ Neu</Text>
        </TouchableOpacity>
      </View>

      {/* Hauptchat-Eintrag (immer oben) */}
      {(() => {
        const dot = _statusDot('__main__');
        return (
          <TouchableOpacity
            onPress={() => switchTo('')}
            style={[s.row, !activeId && s.rowActive]}
          >
            <View style={{ flex: 1 }}>
              <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
                {queueStatus && (
                  <View style={{ width: 8, height: 8, borderRadius: 4, backgroundColor: dot.color }} />
                )}
                <Text style={[s.rowName, !activeId && { color: '#34C759' }]}>💬 Hauptchat</Text>
                {!activeId && <Text style={s.activeBadge}>✓ FOCUS</Text>}
              </View>
              <Text style={s.rowMeta}>
                Standard-Verlauf, keine Projekt-Zuordnung
                {dot.label ? ` · ${dot.label}` : ''}
              </Text>
            </View>
          </TouchableOpacity>
        );
      })()}

      {loading ? (
        <View style={{ padding: 24, alignItems: 'center' }}>
          <ActivityIndicator color="#0096FF" />
        </View>
      ) : err ? (
        <Text style={s.errorText}>⚠ {err}</Text>
      ) : (
        <FlatList
          data={projects}
          keyExtractor={p => p.id}
          renderItem={renderItem}
          ListEmptyComponent={
            <Text style={s.emptyText}>
              Noch keine Projekte. Tipp + Neu oder sag zu ARIA:{'\n'}
              „Lass uns ein Projekt 'XY' anlegen".
            </Text>
          }
        />
      )}

      {/* Neu-Anlegen Modal */}
      <Modal visible={newOpen} animationType="slide" transparent onRequestClose={() => setNewOpen(false)}>
        <View style={s.modalOverlay}>
          <View style={s.modalCard}>
            <Text style={s.modalTitle}>Neues Projekt</Text>
            <TextInput
              value={newName}
              onChangeText={setNewName}
              placeholder="Name (z.B. 'Frankreich-Urlaub')"
              placeholderTextColor="#555570"
              style={s.input}
              autoFocus
            />
            <TextInput
              value={newDesc}
              onChangeText={setNewDesc}
              placeholder="Beschreibung — kurz, hilft beim Wiederfinden"
              placeholderTextColor="#555570"
              style={[s.input, { height: 70 }]}
              multiline
            />
            <View style={{ flexDirection: 'row', gap: 8, marginTop: 12 }}>
              <TouchableOpacity onPress={() => setNewOpen(false)} style={[s.modalBtn, { backgroundColor: '#2A2A3E' }]}>
                <Text style={s.modalBtnText}>Abbrechen</Text>
              </TouchableOpacity>
              <TouchableOpacity onPress={createProject} style={[s.modalBtn, { backgroundColor: '#34C759' }]}>
                <Text style={s.modalBtnText}>Anlegen + aktivieren</Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>

      {/* Edit Modal */}
      <Modal visible={!!editing} animationType="slide" transparent onRequestClose={() => setEditing(null)}>
        <View style={s.modalOverlay}>
          <View style={s.modalCard}>
            <Text style={s.modalTitle}>Projekt bearbeiten</Text>
            <TextInput
              value={editName}
              onChangeText={setEditName}
              placeholder="Name"
              placeholderTextColor="#555570"
              style={s.input}
            />
            <TextInput
              value={editDesc}
              onChangeText={setEditDesc}
              placeholder="Beschreibung"
              placeholderTextColor="#555570"
              style={[s.input, { height: 70 }]}
              multiline
            />
            <View style={{ flexDirection: 'row', gap: 8, marginTop: 12 }}>
              <TouchableOpacity onPress={() => setEditing(null)} style={[s.modalBtn, { backgroundColor: '#2A2A3E' }]}>
                <Text style={s.modalBtnText}>Abbrechen</Text>
              </TouchableOpacity>
              <TouchableOpacity onPress={saveEdit} style={[s.modalBtn, { backgroundColor: '#34C759' }]}>
                <Text style={s.modalBtnText}>Speichern</Text>
              </TouchableOpacity>
            </View>
            {editing && editing.status !== 'ended' && (
              <TouchableOpacity onPress={() => endProject(editing)} style={s.tertiaryBtn}>
                <Text style={s.tertiaryBtnText}>⏹ Projekt beenden</Text>
              </TouchableOpacity>
            )}
            {editing && (
              <TouchableOpacity onPress={() => archiveProject(editing)} style={s.tertiaryBtn}>
                <Text style={[s.tertiaryBtnText, { color: '#E55C5C' }]}>🗑 Archivieren</Text>
              </TouchableOpacity>
            )}
          </View>
        </View>
      </Modal>
    </View>
  );

  // Wenn als Modal genutzt
  if (onClose) {
    return (
      <Modal visible={visible} animationType="slide" onRequestClose={onClose}>
        {body}
      </Modal>
    );
  }
  return body;
};

const s = StyleSheet.create({
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 12,
    paddingVertical: 14,
    borderBottomWidth: 1,
    borderColor: '#1E1E2E',
    backgroundColor: '#080810',
  },
  headerBtn: { padding: 8, minWidth: 60 },
  headerBtnText: { color: '#0096FF', fontSize: 18, fontWeight: '600' },
  headerTitle: { flex: 1, textAlign: 'center', color: '#E0E0F0', fontSize: 18, fontWeight: '700' },
  row: {
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderColor: '#1E1E2E',
  },
  rowActive: {
    backgroundColor: 'rgba(52,199,89,0.08)',
    borderLeftWidth: 3,
    borderLeftColor: '#34C759',
  },
  rowName: { color: '#E0E0F0', fontSize: 16, fontWeight: '600' },
  rowDesc: { color: '#8888AA', fontSize: 13, marginTop: 4 },
  rowMeta: { color: '#555570', fontSize: 11, marginTop: 4 },
  activeBadge: { color: '#34C759', fontSize: 10, fontWeight: '800' },
  statusBadge: { color: '#FFD60A', fontSize: 10, fontWeight: '700',
                 backgroundColor: 'rgba(255,214,10,0.15)', paddingHorizontal: 6,
                 paddingVertical: 2, borderRadius: 4 },
  errorText: { color: '#FF6E6E', padding: 16, textAlign: 'center', fontSize: 13 },
  emptyText: { color: '#555570', padding: 24, textAlign: 'center', fontSize: 13, lineHeight: 19 },
  modalOverlay: {
    flex: 1, backgroundColor: 'rgba(0,0,0,0.6)',
    justifyContent: 'center', paddingHorizontal: 20,
  },
  modalCard: { backgroundColor: '#15151E', borderRadius: 12, padding: 18 },
  modalTitle: { color: '#E0E0F0', fontSize: 18, fontWeight: '700', marginBottom: 14 },
  input: {
    backgroundColor: '#0A0A14', borderRadius: 6, color: '#E0E0F0',
    paddingHorizontal: 12, paddingVertical: 10, fontSize: 14, marginBottom: 8,
    borderWidth: 1, borderColor: '#2A2A3E',
  },
  modalBtn: { flex: 1, alignItems: 'center', paddingVertical: 11, borderRadius: 6 },
  modalBtnText: { color: '#fff', fontSize: 14, fontWeight: '700' },
  tertiaryBtn: { alignItems: 'center', paddingVertical: 10, marginTop: 8 },
  tertiaryBtnText: { color: '#FFD60A', fontSize: 13, fontWeight: '600' },
});

export default ProjectsBrowser;
