import { Ionicons } from '@expo/vector-icons';
import { Image } from 'expo-image';
import { useFocusEffect, useRouter } from 'expo-router';
import { useCallback, useState } from 'react';
import { Pressable, RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { Button } from '@/components/ui';
import { TYPEN, assetsMitBild, type AssetMitBild, type AssetTyp } from '@/lib/assets';
import { useBildQuelle } from '@/lib/bildquelle';
import { reifegrad, type Ordner } from '@/lib/folders';
import { useSession } from '@/lib/session';
import { colors, radius, space, text } from '@/theme/tokens';

export default function ProfilScreen() {
  const router = useRouter();
  const { brand, ordner, aktiverOrdner, setzeAktivenOrdner, ordnerNeuLaden, ausloggen } = useSession();
  const [modelle, setModelle] = useState<AssetMitBild[]>([]);
  const [laedt, setLaedt] = useState(false);

  const laden = useCallback(async () => {
    if (!brand) return;
    setLaedt(true);
    try {
      const [m] = await Promise.all([assetsMitBild(brand.$id), ordnerNeuLaden()]);
      setModelle(m);
    } finally {
      setLaedt(false);
    }
  }, [brand, ordnerNeuLaden]);

  // Nach dem Anlegen kommt man per router.back() zurück – ohne das hier stünde
  // die Liste noch auf dem alten Stand.
  useFocusEffect(
    useCallback(() => {
      void laden();
    }, [laden]),
  );

  return (
    <SafeAreaView style={s.safe} edges={['top', 'left', 'right']}>
      <ScrollView
        contentContainerStyle={s.body}
        refreshControl={<RefreshControl refreshing={laedt} onRefresh={laden} tintColor={colors.mut} />}>
        <Text style={s.marke}>{brand?.label_name ?? 'Profil'}</Text>

        {/* Ordner stehen oben, nicht unter den Metriken – sie sind der Zugang
            zum Wissens-Scope (app-aufbau.md §4.5). */}
        <Abschnitt
          titel="Ordner"
          aktion="Neu"
          aufAktion={() => router.push('/ordner/neu')}
          leer={ordner.length === 0 ? 'Noch kein Ordner. Der erste bestimmt, woraus generiert wird.' : undefined}>
          {ordner.map((o) => (
            <OrdnerZeile
              key={o.$id}
              ordner={o}
              aktiv={o.$id === aktiverOrdner?.$id}
              aufWahl={() => setzeAktivenOrdner(o)}
              aufOeffnen={() => router.push(`/ordner/${o.$id}`)}
            />
          ))}
        </Abschnitt>

        <Abschnitt
          titel="Modelle"
          aktion="Neu"
          aufAktion={() => router.push('/modell/neu')}
          leer={modelle.length === 0 ? 'Noch kein Modell. Personen, Produkte und Kulissen kommen hierher.' : undefined}>
          {TYPEN.map((t) => {
            const davon = modelle.filter((m) => m.typ === t.wert);
            if (!davon.length) return null;
            return (
              <View key={t.wert} style={s.gruppe}>
                <Text style={s.gruppeTitel}>{t.titel}</Text>
                <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={s.reihe}>
                  {davon.map((m) => (
                    <ModellKachel
                      key={m.$id}
                      modell={m}
                      aufDruck={() => router.push({ pathname: '/modell/[id]', params: { id: m.$id } })}
                    />
                  ))}
                </ScrollView>
              </View>
            );
          })}
        </Abschnitt>

        <View style={s.fuss}>
          <Text style={s.fussText}>{brand?.plan ?? 'trial'} · {brand?.$id}</Text>
          <Button title="Abmelden" variant="ghost" onPress={() => void ausloggen()} />
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

function Abschnitt({
  titel, aktion, aufAktion, leer, children,
}: {
  titel: string; aktion: string; aufAktion: () => void; leer?: string; children?: React.ReactNode;
}) {
  return (
    <View style={s.abschnitt}>
      <View style={s.abschnittKopf}>
        <Text style={s.abschnittTitel}>{titel}</Text>
        <Pressable onPress={aufAktion} accessibilityRole="button" style={s.aktion}>
          <Ionicons name="add" size={16} color={colors.accent} />
          <Text style={s.aktionText}>{aktion}</Text>
        </Pressable>
      </View>
      {leer ? <Text style={s.leer}>{leer}</Text> : children}
    </View>
  );
}

function OrdnerZeile({
  ordner, aktiv, aufWahl, aufOeffnen,
}: {
  ordner: Ordner; aktiv: boolean; aufWahl: () => void; aufOeffnen: () => void;
}) {
  return (
    <View style={[s.zeile, aktiv ? s.zeileAktiv : null]}>
      {/* Antippen wählt, der Pfeil öffnet – zwei verschiedene Absichten, die
          man sonst nicht auseinanderhalten kann. */}
      <Pressable
        onPress={aufWahl}
        accessibilityRole="radio"
        accessibilityState={{ selected: aktiv }}
        accessibilityLabel={`${ordner.name} als aktiven Ordner wählen`}
        style={({ pressed }) => [s.zeileText, pressed ? s.gedrueckt : null]}>
        <Text style={s.zeileTitel}>{ordner.name}</Text>
        <Text style={s.zeileUnter}>
          {ordner.zweck === 'sammlung' ? 'Sammlung' : 'Wissens-Scope'} · {reifegrad(ordner)}
        </Text>
      </Pressable>
      {aktiv ? (
        <View style={s.aktivChip}>
          <Text style={s.aktivChipText}>aktiv</Text>
        </View>
      ) : null}
      <Pressable onPress={aufOeffnen} accessibilityRole="button" accessibilityLabel={`${ordner.name} öffnen`} hitSlop={8}>
        <Ionicons name="chevron-forward" size={18} color={colors.faint} />
      </Pressable>
    </View>
  );
}

function ModellKachel({ modell, aufDruck }: { modell: AssetMitBild; aufDruck: () => void }) {
  const quelle = useBildQuelle(modell.titelbildId, modell.titelbildBucket);
  return (
    <Pressable
      onPress={aufDruck}
      accessibilityRole="button"
      accessibilityLabel={`${modell.name} öffnen`}
      style={({ pressed }) => [s.kachel, pressed ? s.gedrueckt : null]}>
      <View>
        {quelle ? (
          <Image source={quelle} style={s.kachelBild} contentFit="cover" transition={150} />
        ) : (
          <View style={[s.kachelBild, s.kachelLeer]}>
            <Ionicons name={iconFuer(modell.typ)} size={22} color={colors.faint} />
          </View>
        )}
        {/* Ohne freigegebene Version ist das Modell nicht einsetzbar – das muss
            man sehen, bevor man es in einem Post auswählen will. */}
        {modell.wartet ? (
          <View style={s.wartetChip}>
            <Text style={s.wartetText}>wählen</Text>
          </View>
        ) : null}
      </View>
      <Text style={s.kachelName} numberOfLines={1}>
        {modell.name}
      </Text>
    </Pressable>
  );
}

function iconFuer(typ: AssetTyp): keyof typeof Ionicons.glyphMap {
  return (TYPEN.find((t) => t.wert === typ)?.icon ?? 'cube-outline') as keyof typeof Ionicons.glyphMap;
}

const s = StyleSheet.create({
  safe: { flex: 1, backgroundColor: colors.bg },
  body: { padding: space.xl, gap: space.xl, paddingBottom: space.xxl },
  marke: { ...text.title, color: colors.txt },

  abschnitt: { gap: space.md },
  abschnittKopf: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' },
  abschnittTitel: { ...text.heading, color: colors.txt },
  aktion: { flexDirection: 'row', alignItems: 'center', gap: 2, paddingVertical: space.xs, paddingHorizontal: space.sm },
  aktionText: { ...text.label, color: colors.accent, fontWeight: '600' },
  leer: { ...text.body, color: colors.faint, lineHeight: 21 },

  zeile: {
    flexDirection: 'row', alignItems: 'center', gap: space.md,
    backgroundColor: colors.surface,
    borderColor: colors.border, borderWidth: StyleSheet.hairlineWidth,
    borderRadius: radius.md, padding: space.lg,
  },
  zeileAktiv: { borderColor: colors.accent, backgroundColor: 'rgba(255,92,57,0.08)' },
  gedrueckt: { opacity: 0.8 },
  zeileText: { flex: 1, gap: 2 },
  zeileTitel: { ...text.body, fontWeight: '600', color: colors.txt },
  zeileUnter: { ...text.label, color: colors.mut },
  aktivChip: { backgroundColor: colors.accent, borderRadius: radius.pill, paddingHorizontal: space.md, paddingVertical: 3 },
  aktivChipText: { fontSize: 11, fontWeight: '700', color: '#fff' },

  gruppe: { gap: space.sm },
  gruppeTitel: { ...text.label, color: colors.faint, textTransform: 'uppercase', letterSpacing: 0.5 },
  reihe: { gap: space.md, paddingRight: space.xl },
  kachel: { width: 104, gap: space.sm },
  kachelBild: {
    width: 104, height: 104, borderRadius: radius.md,
    backgroundColor: colors.surface,
    borderColor: colors.border, borderWidth: StyleSheet.hairlineWidth,
  },
  kachelLeer: { alignItems: 'center', justifyContent: 'center' },
  kachelName: { ...text.label, color: colors.mut },
  wartetChip: {
    position: 'absolute', bottom: 5, left: 5,
    backgroundColor: colors.gold, borderRadius: radius.pill,
    paddingHorizontal: space.sm, paddingVertical: 1,
  },
  wartetText: { fontSize: 10, fontWeight: '700', color: '#000' },

  fuss: { gap: space.md, marginTop: space.md },
  fussText: { ...text.mono, color: colors.faint },
});
