/**
 * FilesTile — Datei-Browser eines Projekts (/shared/projects/<id>/).
 *
 * Listet ALLE Dateien (nicht nur Code): erzeugte Bilder, Logs, Assets … — die
 * gleichen, die in der Projektliste als 📄 gezaehlt werden. Tippen auf ein Bild
 * zeigt es; tippen auf eine Textdatei zeigt eine Vorschau.
 */

import React, { useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, Image, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import brainApi from '../../services/brainApi';

interface Props {
  projectId: string;
  focused: boolean;
}

interface FileEntry { path: string; size: number }

const IMG_EXT = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'];

function ext(path: string): string { return (path.split('.').pop() || '').toLowerCase(); }
function isImage(path: string): boolean { return IMG_EXT.includes(ext(path)); }
function iconFor(path: string): string {
  const e = ext(path);
  if (isImage(path)) return '🖼️';
  if (['md', 'txt', 'readme'].includes(e)) return '📄';
  if (['asm', 's', 'c', 'h', 'cpp', 'py', 'js', 'ts', 'sh', 'go', 'rs'].includes(e)) return '📝';
  if (['zip', 'tar', 'gz', 'img', 'iso', 'qcow2'].includes(e)) return '📦';
  return '📄';
}
function humanSize(n: number): string {
  if (n < 1024) return `${n} B`;
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
  return `${(n / 1024 / 1024).toFixed(1)} MB`;
}

const FilesTile: React.FC<Props> = ({ projectId, focused }) => {
  const [files, setFiles] = useState<FileEntry[]>([]);
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState('');
  const [preview, setPreview] = useState<{ path: string; kind: 'image' | 'text'; data: string } | null>(null);
  const [previewBusy, setPreviewBusy] = useState('');

  const load = useCallback(() => {
    setLoading(true); setErr('');
    brainApi.listProjectFiles(projectId)
      .then(r => setFiles((r.files || []).slice().sort((a, b) => a.path.localeCompare(b.path))))
      .catch(e => setErr(String(e?.message || e)))
      .finally(() => setLoading(false));
  }, [projectId]);

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

  const open = useCallback((f: FileEntry) => {
    setPreviewBusy(f.path); setErr('');
    if (isImage(f.path)) {
      brainApi.readProjectFileBinary(projectId, f.path)
        .then(r => setPreview({ path: f.path, kind: 'image', data: `data:${r.mime};base64,${r.base64}` }))
        .catch(e => setErr(String(e?.message || e)))
        .finally(() => setPreviewBusy(''));
    } else {
      brainApi.readProjectFile(projectId, f.path)
        .then(r => setPreview({ path: f.path, kind: 'text', data: r.content ?? '' }))
        .catch(e => setErr(String(e?.message || e)))
        .finally(() => setPreviewBusy(''));
    }
  }, [projectId]);

  if (!focused) {
    return (
      <View style={styles.placeholder}>
        <Text style={styles.icon}>📁</Text>
        <Text style={styles.text}>Dateien</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <View style={styles.bar}>
        <Text style={styles.barTitle}>Dateien{files.length ? ` (${files.length})` : ''}</Text>
        <TouchableOpacity onPress={load} style={styles.barBtn}><Text style={styles.barBtnText}>↻</Text></TouchableOpacity>
      </View>
      <ScrollView contentContainerStyle={{ padding: 8 }}>
        {loading && files.length === 0 ? (
          <ActivityIndicator color="#0096FF" style={{ marginTop: 20 }} />
        ) : err ? (
          <Text style={styles.err}>{err}</Text>
        ) : files.length === 0 ? (
          <Text style={styles.empty}>Noch keine Dateien in diesem Projekt.</Text>
        ) : (
          files.map(f => (
            <TouchableOpacity key={f.path} onPress={() => open(f)} style={styles.row} disabled={previewBusy === f.path}>
              <Text style={styles.rowIcon}>{iconFor(f.path)}</Text>
              <Text style={styles.rowName} numberOfLines={1}>{f.path}</Text>
              {previewBusy === f.path
                ? <ActivityIndicator color="#8888AA" size="small" />
                : <Text style={styles.rowSize}>{humanSize(f.size)}</Text>}
            </TouchableOpacity>
          ))
        )}
      </ScrollView>

      <Modal visible={!!preview} transparent animationType="fade" onRequestClose={() => setPreview(null)}>
        <View style={styles.pvOverlay}>
          <View style={styles.pvBar}>
            <Text style={styles.pvTitle} numberOfLines={1}>{preview?.path}</Text>
            <TouchableOpacity onPress={() => setPreview(null)}><Text style={styles.pvClose}>✕</Text></TouchableOpacity>
          </View>
          {preview?.kind === 'image' ? (
            <Image source={{ uri: preview.data }} style={styles.pvImg} resizeMode="contain" />
          ) : (
            <ScrollView style={styles.pvTextWrap} horizontal>
              <ScrollView><Text style={styles.pvText}>{preview?.data}</Text></ScrollView>
            </ScrollView>
          )}
        </View>
      </Modal>
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#0D0D1A' },
  placeholder: { flex: 1, backgroundColor: '#0D0D1A', alignItems: 'center', justifyContent: 'center' },
  icon: { fontSize: 56, marginBottom: 10 },
  text: { color: '#FFFFFF', fontSize: 18, fontWeight: '700' },
  bar: { height: 40, flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, backgroundColor: '#12122A', borderBottomColor: '#1E1E2E', borderBottomWidth: 1 },
  barTitle: { color: '#E0E0F0', fontSize: 14, fontWeight: '700', flex: 1 },
  barBtn: { paddingHorizontal: 10, paddingVertical: 4 },
  barBtnText: { color: '#0096FF', fontSize: 14, fontWeight: '700' },
  empty: { color: '#8888AA', fontSize: 13, textAlign: 'center', marginTop: 24 },
  err: { color: '#FF6E6E', fontSize: 13, marginTop: 16, paddingHorizontal: 8 },
  row: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10, paddingHorizontal: 8, borderBottomColor: '#161628', borderBottomWidth: 1, gap: 10 },
  rowIcon: { fontSize: 18 },
  rowName: { color: '#E0E0F0', fontSize: 13, flex: 1 },
  rowSize: { color: '#555570', fontSize: 11 },
  pvOverlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.94)' },
  pvBar: { flexDirection: 'row', alignItems: 'center', padding: 12, gap: 10 },
  pvTitle: { color: '#E0E0F0', fontSize: 13, fontWeight: '700', flex: 1 },
  pvClose: { color: '#E0E0F0', fontSize: 20, paddingHorizontal: 6 },
  pvImg: { flex: 1, width: '100%' },
  pvTextWrap: { flex: 1, padding: 12 },
  pvText: { color: '#C8C8E0', fontSize: 12, fontFamily: 'monospace' },
});

export default FilesTile;
