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

import { Button, ErrorNote, Field } from '@/components/ui';
import { Wahl } from '@/components/wahl';
import {
  BILDER_EMPFOHLEN,
  BILDER_MAX,
  kannGenerieren,
  TYPEN,
  VARIANTEN_JE_MODELL,
  assetAnlegen,
  type AssetTyp,
} from '@/lib/assets';
import { fehlertext } from '@/lib/auth';
import { useSession } from '@/lib/session';
import type { Auswahl } from '@/lib/upload';
import { colors, radius, space, text } from '@/theme/tokens';

export default function ModellNeuScreen() {
  const router = useRouter();
  const { brand } = useSession();

  const [typ, setTyp] = useState<AssetTyp>('gesicht');
  const [name, setName] = useState('');
  const [beschreibung, setBeschreibung] = useState('');
  const [merkmale, setMerkmale] = useState('');
  const [bilder, setBilder] = useState<Auswahl[]>([]);
  const [fehler, setFehler] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  async function bilderWaehlen() {
    const res = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: 'images',
      allowsMultipleSelection: true,
      selectionLimit: BILDER_MAX - bilder.length,
      quality: 0.9,
    });
    if (res.canceled) return;
    const neu: Auswahl[] = res.assets.map((a, i) => ({
      uri: a.uri,
      name: a.fileName ?? `referenz-${Date.now()}-${i}.jpg`,
      mimeType: a.mimeType ?? 'image/jpeg',
      size: a.fileSize ?? 0,
    }));
    setBilder((b) => [...b, ...neu].slice(0, BILDER_MAX));
  }

  async function anlegen() {
    if (!brand?.team_id) {
      setFehler('Zur Marke ist kein Team hinterlegt – bitte neu anmelden.');
      return;
    }
    setFehler(null);
    setBusy(true);
    try {
      const asset = await assetAnlegen(brand.$id, brand.team_id, {
        typ,
        name: name.trim(),
        beschreibung: beschreibung.trim(),
        merkmale: merkmale.split('\n').map((z) => z.trim()).filter(Boolean),
        bilder,
      });
      // Bei generierbaren Typen wartet dort die Auswahl der Variante.
      if (kannGenerieren(typ, bilder.length > 0)) router.replace({ pathname: '/modell/[id]', params: { id: asset.$id } });
      else router.back();
    } catch (e) {
      setFehler(fehlertext(e));
      setBusy(false);
    }
  }

  const zuViele = bilder.length > 7;

  return (
    <SafeAreaView style={s.safe} edges={['top', 'left', 'right']}>
      <ScrollView contentContainerStyle={s.body} keyboardShouldPersistTaps="handled">
        <Text style={s.titel}>Modell anlegen</Text>
        <Text style={s.unter}>
          Ein Modell ist das, was im Bild zu sehen ist – eine Person, ein Produkt oder eine Kulisse.
          Es wird wiederverwendet, damit es überall gleich aussieht.
        </Text>

        {fehler ? <ErrorNote message={fehler} /> : null}

        <Wahl label="Was ist es?" optionen={TYPEN} wert={typ} aufWahl={setTyp} />

        <Field label="Name" value={name} onChangeText={setName} placeholder="z. B. Serum 30 ml" />
        <Field
          label="Beschreibung"
          value={beschreibung}
          onChangeText={setBeschreibung}
          placeholder="Für Menschen lesbar – was dieses Modell ausmacht."
          multiline
          numberOfLines={4}
          style={s.mehrzeilig}
        />

        <View style={s.block}>
          <Field
            label="Merkmale – eines pro Zeile, englisch"
            value={merkmale}
            onChangeText={setMerkmale}
            placeholder={'long straight blonde hair with a centre parting\nwarm fair skin tone\noval face with pronounced cheekbones'}
            multiline
            numberOfLines={6}
            autoCapitalize="none"
            style={s.mehrzeilig}
          />
          <Text style={s.hinweis}>
            Diese Zeilen gehen <Text style={s.betont}>wörtlich</Text> in den Prompt – umformulieren
            heißt, die Identität zu verlieren. Keine Namen, keine Fremdmarken, keine Altersangaben.
          </Text>
        </View>

        <View style={s.block}>
          <Text style={s.label}>Referenzbilder</Text>
          <Text style={s.hinweis}>
            {kannGenerieren(typ, bilder.length > 0)
              ? `Optional. ${BILDER_EMPFOHLEN} bis ${BILDER_MAX} sind das Optimum – mehr als sieben mitteln die Merkmale weg, statt sie zu schärfen.`
              : 'Pflicht. Das Logo wird genau so verwendet, wie du es hochlädst.'}
          </Text>

          <View style={s.gitter}>
            {bilder.map((b, i) => (
              <View key={`${b.uri}-${i}`} style={s.kachel}>
                <Image source={{ uri: b.uri }} style={s.vorschau} contentFit="cover" />
                <Pressable
                  onPress={() => setBilder((alt) => alt.filter((_, j) => j !== i))}
                  style={s.weg}
                  accessibilityLabel="Bild entfernen">
                  <Ionicons name="close" size={14} color="#fff" />
                </Pressable>
              </View>
            ))}
            {bilder.length < BILDER_MAX ? (
              <Pressable onPress={bilderWaehlen} style={[s.kachel, s.plus]} accessibilityLabel="Bilder auswählen">
                <Ionicons name="add" size={26} color={colors.mut} />
              </Pressable>
            ) : null}
          </View>

          {zuViele ? <Text style={s.warnung}>Über sieben Bilder verschlechtern die Konsistenz.</Text> : null}
        </View>

        {typ === 'logo' ? (
          <View style={s.regelBox}>
            <Ionicons name="lock-closed-outline" size={15} color={colors.gold} />
            <Text style={s.regelText}>
              {bilder.length > 0 ? (
                <>
                  Dein Logo wird <Text style={s.betont}>unverändert übernommen</Text> und ab jetzt
                  nie neu erzeugt. So verlangt es eure Brand-Regel: nicht verzerren, nicht
                  beschneiden, nicht umfärben, nicht neu interpretieren.
                </>
              ) : (
                <>
                  Ohne Datei entwerfe ich <Text style={s.betont}>Vorschläge</Text>. Das geht nur,
                  solange es kein Logo gibt – sobald du eines freigibst, wird es geschützt und
                  nicht mehr generiert.
                </>
              )}
            </Text>
          </View>
        ) : null}

        <View style={s.actions}>
          <Button
            title={
              kannGenerieren(typ, bilder.length > 0)
                ? `Anlegen und ${VARIANTEN_JE_MODELL} Varianten erzeugen`
                : 'Logo unverändert übernehmen'
            }
            onPress={anlegen}
            busy={busy}
            // Referenzbilder sind beim Generieren **optional** – sie schärfen
            // die Identität, ersetzen aber nicht die Beschreibung. Wird
            // stattdessen hochgeladen, ist die Datei der ganze Inhalt.
            disabled={
              name.trim().length < 2 ||
              (kannGenerieren(typ, bilder.length > 0)
                ? beschreibung.trim().length < 10
                : bilder.length === 0)
            }
          />
          <Button title="Abbrechen" variant="ghost" onPress={() => router.back()} />
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

const s = StyleSheet.create({
  safe: { flex: 1, backgroundColor: colors.bg },
  body: { padding: space.xl, gap: space.lg, paddingBottom: space.xxl },
  titel: { ...text.title, color: colors.txt },
  unter: { ...text.body, color: colors.mut, lineHeight: 21, marginTop: -space.sm },
  mehrzeilig: { minHeight: 100, textAlignVertical: 'top' },
  block: { gap: space.sm },
  label: { ...text.label, color: colors.mut },
  hinweis: { ...text.label, color: colors.faint, lineHeight: 18 },
  betont: { color: colors.mut, fontWeight: '700' },
  gitter: { flexDirection: 'row', flexWrap: 'wrap', gap: space.md, marginTop: space.sm },
  kachel: {
    width: 88, height: 88, borderRadius: radius.sm, overflow: 'hidden',
    backgroundColor: colors.surface,
    borderColor: colors.border, borderWidth: StyleSheet.hairlineWidth,
  },
  vorschau: { width: '100%', height: '100%' },
  weg: {
    position: 'absolute', top: 4, right: 4,
    width: 22, height: 22, borderRadius: 11,
    backgroundColor: 'rgba(0,0,0,0.6)',
    alignItems: 'center', justifyContent: 'center',
  },
  plus: { alignItems: 'center', justifyContent: 'center', borderStyle: 'dashed' },
  warnung: { ...text.label, color: colors.gold },
  regelBox: {
    flexDirection: 'row', gap: space.md, alignItems: 'flex-start',
    backgroundColor: 'rgba(251,191,36,0.10)',
    borderColor: colors.gold, borderWidth: StyleSheet.hairlineWidth,
    borderRadius: radius.md, padding: space.lg,
  },
  regelText: { ...text.label, color: colors.mut, lineHeight: 19, flex: 1 },
  actions: { gap: space.md, marginTop: space.md },
});
