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

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

type Mode = 'pin' | 'recovery';

export default function UnlockScreen() {
  const router = useRouter();
  const { userId, userKeyState, refreshUserKeyState } = useAuth();
  const [mode, setMode] = useState<Mode>('pin');
  const [pin, setPin] = useState('');
  const [recovery, setRecovery] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const locked =
    userKeyState.status === 'needs-unlock' && userKeyState.lockedUntil !== null;
  const hasRecovery =
    userKeyState.status === 'needs-unlock' ? userKeyState.hasRecovery : false;

  async function attempt(value: string, isRecoveryCode: boolean) {
    if (!userId) return;
    setSubmitting(true);
    setError(null);
    try {
      const out = await loadOrUnlockUserKey({ userId, pin: value, isRecoveryCode });
      if (out.kind === 'unlocked') {
        await refreshUserKeyState();
        router.replace('/(app)/chats');
        return;
      }
      if (out.kind === 'locked') {
        setError('Konto bis ' + new Date(out.lockedUntil).toLocaleString('de-DE') + ' gesperrt.');
        await refreshUserKeyState();
        return;
      }
      setError('Kein Identitäts-Datensatz auf dem Server.');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Entsperren fehlgeschlagen');
      if (isRecoveryCode) setRecovery('');
      else setPin('');
      await refreshUserKeyState();
    } finally {
      setSubmitting(false);
    }
  }

  async function handleReset() {
    if (!userId) return;
    setSubmitting(true);
    setError(null);
    try {
      await resetIdentity({ userId, pin: '000000' });
      await refreshUserKeyState();
      router.replace('/(app)/setup');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Reset fehlgeschlagen');
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Netralax entsperren</Text>
      <View style={styles.tabs}>
        <Pressable
          style={[styles.tab, mode === 'pin' && styles.tabActive]}
          onPress={() => setMode('pin')}
        >
          <Text style={[styles.tabText, mode === 'pin' && styles.tabTextActive]}>PIN</Text>
        </Pressable>
        <Pressable
          style={[styles.tab, mode === 'recovery' && styles.tabActive]}
          disabled={!hasRecovery}
          onPress={() => setMode('recovery')}
        >
          <Text style={[styles.tabText, mode === 'recovery' && styles.tabTextActive]}>
            Recovery-Code
          </Text>
        </Pressable>
      </View>

      {mode === 'pin' ? (
        <>
          <PinInput
            value={pin}
            onChange={setPin}
            ariaLabel="PIN eingeben"
            autoFocus
            disabled={locked || submitting}
          />
          <Pressable
            style={[styles.primary, (pin.length !== 6 || locked || submitting) && styles.disabled]}
            disabled={pin.length !== 6 || locked || submitting}
            onPress={() => attempt(pin, false)}
          >
            {submitting ? (
              <ActivityIndicator color={colors.text} />
            ) : (
              <Text style={styles.primaryText}>Entsperren</Text>
            )}
          </Pressable>
        </>
      ) : (
        <>
          <Text style={styles.subtitle}>Recovery-Code eingeben (mit oder ohne Bindestriche):</Text>
          <Text style={styles.recoveryDisplay} selectable>
            {recovery}
          </Text>
          <Pressable
            style={[styles.primary, recovery.length === 0 && styles.disabled]}
            disabled={recovery.length === 0 || submitting}
            onPress={() => attempt(recovery, true)}
          >
            {submitting ? (
              <ActivityIndicator color={colors.text} />
            ) : (
              <Text style={styles.primaryText}>Mit Recovery entsperren</Text>
            )}
          </Pressable>
        </>
      )}

      {error && <Text style={styles.error}>{error}</Text>}

      {locked && (
        <Pressable style={styles.danger} onPress={handleReset}>
          <Text style={styles.dangerText}>Identität zurücksetzen (alte Chats verloren)</Text>
        </Pressable>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.bg,
    paddingTop: 64,
    paddingHorizontal: 24,
    gap: 16,
  },
  title: { color: colors.text, fontSize: 22, fontWeight: '700' },
  subtitle: { color: colors.textMuted, fontSize: 13 },
  tabs: { flexDirection: 'row', gap: 8 },
  tab: {
    flex: 1,
    paddingVertical: 10,
    alignItems: 'center',
    borderBottomWidth: 2,
    borderBottomColor: colors.border,
  },
  tabActive: { borderBottomColor: colors.accent },
  tabText: { color: colors.textMuted, fontWeight: '600' },
  tabTextActive: { color: colors.text },
  recoveryDisplay: {
    color: colors.text,
    fontFamily: 'Courier',
    fontSize: 18,
    letterSpacing: 1.5,
    backgroundColor: colors.surface,
    padding: 16,
    borderRadius: 10,
  },
  primary: {
    backgroundColor: colors.accent,
    paddingVertical: 14,
    borderRadius: 12,
    alignItems: 'center',
  },
  primaryText: { color: colors.text, fontWeight: '700' },
  disabled: { opacity: 0.5 },
  danger: {
    paddingVertical: 12,
    alignItems: 'center',
    borderColor: colors.danger,
    borderWidth: 1,
    borderRadius: 12,
  },
  dangerText: { color: colors.danger, fontWeight: '700' },
  error: { color: colors.danger, fontSize: 13 },
});
