import { useRouter } from 'expo-router';
import { useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from 'react-native';

import { PinInput } from '../../components/PinInput';
import { useAuth } from '../../lib/authContext';
import { setupNewUserIdentity } from '../../lib/userIdentity';
import { colors } from '../../theme/colors';

type Step = 'pin' | 'confirm' | 'recovery' | 'done';

export default function SetupScreen() {
  const router = useRouter();
  const { userId, refreshUserKeyState } = useAuth();
  const [step, setStep] = useState<Step>('pin');
  const [pin, setPin] = useState('');
  const [confirm, setConfirm] = useState('');
  const [recoveryCode, setRecoveryCode] = useState<string | null>(null);
  const [withRecovery, setWithRecovery] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function runSetup(saveRecovery: boolean) {
    if (!userId) return;
    setSubmitting(true);
    setError(null);
    try {
      const out = await setupNewUserIdentity({ userId, pin, withRecovery: saveRecovery });
      setRecoveryCode(out.recoveryCode);
      if (out.recoveryCode) {
        setStep('recovery');
      } else {
        setStep('done');
        await refreshUserKeyState();
        router.replace('/(app)/chats');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Setup fehlgeschlagen');
    } finally {
      setSubmitting(false);
    }
  }

  if (step === 'pin') {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>PIN festlegen</Text>
        <Text style={styles.subtitle}>
          Mit dieser 6-stelligen PIN entsperrst du Netralax auf jedem Gerät.
        </Text>
        <PinInput value={pin} onChange={setPin} ariaLabel="Neue PIN" autoFocus />
        {error && <Text style={styles.error}>{error}</Text>}
        <Pressable
          style={[styles.primary, pin.length !== 6 && styles.disabled]}
          disabled={pin.length !== 6}
          onPress={() => setStep('confirm')}
        >
          <Text style={styles.primaryText}>Weiter</Text>
        </Pressable>
      </View>
    );
  }

  if (step === 'confirm') {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>PIN bestätigen</Text>
        <Text style={styles.subtitle}>Bitte gib dieselbe PIN erneut ein.</Text>
        <PinInput value={confirm} onChange={setConfirm} ariaLabel="PIN bestätigen" autoFocus />
        {error && <Text style={styles.error}>{error}</Text>}
        <Pressable
          style={[styles.primary, confirm.length !== 6 && styles.disabled]}
          disabled={confirm.length !== 6 || submitting}
          onPress={() => {
            if (pin !== confirm) {
              setError('PIN stimmt nicht überein.');
              setConfirm('');
              return;
            }
            void runSetup(withRecovery);
          }}
        >
          {submitting ? (
            <ActivityIndicator color={colors.text} />
          ) : (
            <Text style={styles.primaryText}>PIN speichern</Text>
          )}
        </Pressable>
        <Pressable onPress={() => setWithRecovery((v) => !v)} style={styles.secondary}>
          <Text style={styles.secondaryText}>
            {withRecovery
              ? 'Recovery-Code überspringen (riskant)'
              : 'Recovery-Code erzeugen (empfohlen)'}
          </Text>
        </Pressable>
      </View>
    );
  }

  if (step === 'recovery' && recoveryCode) {
    return (
      <ScrollView contentContainerStyle={styles.container}>
        <Text style={styles.title}>Recovery-Code</Text>
        <Text style={styles.subtitle}>
          Notiere dir diesen Code an einem sicheren Ort. Du brauchst ihn, wenn du deine PIN
          vergisst. Wir zeigen ihn dir nur EINMAL.
        </Text>
        <View style={styles.codeBox}>
          <Text style={styles.codeText} selectable>
            {recoveryCode}
          </Text>
        </View>
        <Pressable
          style={styles.primary}
          onPress={async () => {
            await refreshUserKeyState();
            router.replace('/(app)/chats');
          }}
        >
          <Text style={styles.primaryText}>Habe ich gespeichert</Text>
        </Pressable>
        <Pressable
          style={styles.secondary}
          onPress={() => {
            Alert.alert(
              'Sicher?',
              'Ohne Recovery-Code verlierst du den Zugriff, wenn du die PIN vergisst.',
              [
                { text: 'Abbrechen', style: 'cancel' },
                {
                  text: 'Weiter ohne',
                  style: 'destructive',
                  onPress: async () => {
                    await refreshUserKeyState();
                    router.replace('/(app)/chats');
                  },
                },
              ],
            );
          }}
        >
          <Text style={styles.secondaryText}>Überspringen</Text>
        </Pressable>
      </ScrollView>
    );
  }

  return null;
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    paddingTop: 64,
    backgroundColor: colors.bg,
    gap: 16,
  },
  title: { color: colors.text, fontSize: 24, fontWeight: '700' },
  subtitle: { color: colors.textMuted, fontSize: 14, lineHeight: 20 },
  error: { color: colors.danger, fontSize: 13 },
  primary: {
    backgroundColor: colors.accent,
    paddingVertical: 14,
    borderRadius: 12,
    alignItems: 'center',
    marginTop: 12,
  },
  primaryText: { color: colors.text, fontWeight: '700' },
  disabled: { opacity: 0.5 },
  secondary: { paddingVertical: 12, alignItems: 'center' },
  secondaryText: { color: colors.accent, fontWeight: '600' },
  codeBox: {
    backgroundColor: colors.surface,
    borderColor: colors.border,
    borderWidth: 1,
    padding: 16,
    borderRadius: 12,
  },
  codeText: {
    color: colors.text,
    fontSize: 20,
    fontFamily: 'Courier',
    letterSpacing: 1.5,
    textAlign: 'center',
  },
});
