import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Linking,
  Pressable,
  ScrollView,
  StyleSheet,
  Switch,
  Text,
  View,
} from 'react-native';
import {
  AppLockSettings,
  biometricAvailable,
  clearPin,
  DEFAULT_TIMEOUT_SECONDS,
  getSettings,
  setBioEnabled,
  setEnabled,
  setPin,
  setTimeoutSeconds,
  verifyPin,
} from '../lib/applock';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { APP_VERSION } from '../lib/appVersion';
import { replayOnboarding } from '../lib/onboardingBus';
import { usePreferences } from '../PreferencesContext';
import type { DefaultQuality } from '../storage';
import type { RootStackParamList } from '../navigation';
import { theme } from '../theme';
import { PinEntry } from './PinEntry';

const TIMEOUT_OPTIONS: { label: string; seconds: number }[] = [
  { label: 'Immediately', seconds: 0 },
  { label: '30 sec', seconds: 30 },
  { label: '1 min', seconds: 60 },
  { label: '5 min', seconds: 300 },
  { label: '15 min', seconds: 900 },
];

const QUALITY_OPTIONS: { label: string; value: DefaultQuality }[] = [
  { label: 'Ask', value: 'auto' },
  { label: '4K', value: 2160 },
  { label: '1080p', value: 1080 },
  { label: '720p', value: 720 },
  { label: '480p', value: 480 },
  { label: 'Lowest', value: 'lowest' },
];

type Stage = 'menu' | 'enter-current' | 'set-new' | 'confirm-new' | 'disable-confirm';

export function AppLockSettingsScreen() {
  const [settings, setSettings] = useState<AppLockSettings | null>(null);
  const [bioAvailable, setBioAvailable] = useState(false);
  const [stage, setStage] = useState<Stage>('menu');
  const [newPin, setNewPin] = useState('');
  const [errorText, setErrorText] = useState<string | null>(null);
  const { gridColumns, setGridColumns, defaultQuality, setDefaultQuality } = usePreferences();
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();

  async function refresh() {
    const [s, bio] = await Promise.all([getSettings(), biometricAvailable()]);
    setSettings(s);
    setBioAvailable(bio);
  }

  useEffect(() => {
    refresh();
  }, []);

  if (!settings) {
    return (
      <View style={styles.center}>
        <ActivityIndicator color={theme.muted} />
      </View>
    );
  }

  if (stage === 'enter-current') {
    return (
      <PinEntry
        title="Enter current PIN"
        error={errorText}
        onCancel={() => {
          setStage('menu');
          setErrorText(null);
        }}
        onSubmit={async (candidate) => {
          const ok = await verifyPin(candidate);
          if (!ok) {
            setErrorText('Incorrect PIN');
            return;
          }
          setErrorText(null);
          setStage('set-new');
        }}
      />
    );
  }

  if (stage === 'set-new') {
    return (
      <PinEntry
        title="Enter new PIN (4-8 digits)"
        error={errorText}
        onCancel={() => {
          setStage('menu');
          setErrorText(null);
          setNewPin('');
        }}
        onSubmit={async (candidate) => {
          if (candidate.length < 4) {
            setErrorText('Min. 4 digits');
            return;
          }
          setNewPin(candidate);
          setErrorText(null);
          setStage('confirm-new');
        }}
      />
    );
  }

  if (stage === 'confirm-new') {
    return (
      <PinEntry
        title="Confirm PIN"
        error={errorText}
        onCancel={() => {
          setStage('menu');
          setErrorText(null);
          setNewPin('');
        }}
        onSubmit={async (candidate) => {
          if (candidate !== newPin) {
            setErrorText('PINs do not match');
            return;
          }
          await setPin(newPin);
          await setEnabled(true);
          setNewPin('');
          setErrorText(null);
          setStage('menu');
          await refresh();
          Alert.alert('Done', 'PIN saved. App lock enabled.');
        }}
      />
    );
  }

  if (stage === 'disable-confirm') {
    return (
      <PinEntry
        title="Enter PIN to disable lock"
        error={errorText}
        onCancel={() => {
          setStage('menu');
          setErrorText(null);
        }}
        onSubmit={async (candidate) => {
          const ok = await verifyPin(candidate);
          if (!ok) {
            setErrorText('Incorrect PIN');
            return;
          }
          await setEnabled(false);
          await setBioEnabled(false);
          await clearPin();
          setErrorText(null);
          setStage('menu');
          await refresh();
        }}
      />
    );
  }

  return (
    <ScrollView style={styles.root} contentContainerStyle={{ paddingBottom: 40 }}>
      <View style={styles.section}>
        <Text style={styles.sectionTitle}>App lock</Text>

        <View style={styles.row}>
          <View style={{ flex: 1 }}>
            <Text style={styles.label}>Enabled</Text>
            <Text style={styles.hint}>
              {settings.enabled ? 'Requires PIN at startup and after a break' : 'Disabled'}
            </Text>
          </View>
          <Switch
            value={settings.enabled}
            onValueChange={(v) => {
              if (v) {
                setStage('set-new');
              } else if (settings.hasPin) {
                setStage('disable-confirm');
              } else {
                setEnabled(false).then(refresh);
              }
            }}
            trackColor={{ true: theme.accent, false: theme.border }}
            thumbColor={theme.fg}
          />
        </View>

        {settings.enabled && settings.hasPin ? (
          <Pressable
            style={styles.actionBtn}
            onPress={() => {
              setStage('enter-current');
              setErrorText(null);
            }}
          >
            <Text style={styles.actionText}>Change PIN</Text>
          </Pressable>
        ) : null}
      </View>

      {settings.enabled ? (
        <>
          <View style={styles.section}>
            <Text style={styles.sectionTitle}>Biometrics</Text>
            <View style={styles.row}>
              <View style={{ flex: 1 }}>
                <Text style={styles.label}>Fingerprint / Face Unlock</Text>
                <Text style={styles.hint}>
                  {bioAvailable
                    ? 'Faster unlocking, PIN as fallback'
                    : 'No biometrics on this device'}
                </Text>
              </View>
              <Switch
                value={settings.bioEnabled && bioAvailable}
                disabled={!bioAvailable}
                onValueChange={async (v) => {
                  await setBioEnabled(v);
                  await refresh();
                }}
                trackColor={{ true: theme.accent, false: theme.border }}
                thumbColor={theme.fg}
              />
            </View>
          </View>

          <View style={styles.section}>
            <Text style={styles.sectionTitle}>Time until lock</Text>
            <Text style={styles.hint}>How long to wait after leaving the app before locking</Text>
            <View style={styles.chipRow}>
              {TIMEOUT_OPTIONS.map((opt) => {
                const active = settings.timeoutSeconds === opt.seconds;
                return (
                  <Pressable
                    key={opt.seconds}
                    style={[styles.chip, active && styles.chipActive]}
                    onPress={async () => {
                      await setTimeoutSeconds(opt.seconds);
                      await refresh();
                    }}
                  >
                    <Text style={[styles.chipText, active && styles.chipTextActive]}>
                      {opt.label}
                    </Text>
                  </Pressable>
                );
              })}
            </View>
          </View>
        </>
      ) : null}

      <View style={styles.section}>
        <Text style={styles.hint}>
          The app is also hidden in the recent apps list and blocks screenshots.
        </Text>
      </View>

      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Content</Text>
        <Pressable style={styles.row} onPress={() => navigation.navigate('Blacklist')}>
          <View style={{ flex: 1 }}>
            <Text style={styles.label}>Hidden content</Text>
            <Text style={styles.hint}>Hide tags, performers or studios you never want to see</Text>
          </View>
          <Text style={styles.linkValue}>›</Text>
        </Pressable>
      </View>

      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Grid</Text>
        <Text style={styles.hint}>Thumbnails per row in scene lists</Text>
        <View style={styles.chipRow}>
          {[1, 2, 3].map((n) => {
            const active = gridColumns === n;
            return (
              <Pressable
                key={n}
                style={[styles.chip, active && styles.chipActive]}
                onPress={() => setGridColumns(n)}
              >
                <Text style={[styles.chipText, active && styles.chipTextActive]}>
                  {n === 1 ? '1 column' : `${n} columns`}
                </Text>
              </Pressable>
            );
          })}
        </View>
      </View>

      <View style={styles.section}>
        <Text style={styles.sectionTitle}>Playback</Text>
        <Text style={styles.hint}>
          Default quality, auto-picked when available so you skip the chooser. "Ask" shows
          the quality menu every time (movie parts always ask).
        </Text>
        <View style={styles.chipRow}>
          {QUALITY_OPTIONS.map((opt) => {
            const active = defaultQuality === opt.value;
            return (
              <Pressable
                key={String(opt.value)}
                style={[styles.chip, active && styles.chipActive]}
                onPress={() => setDefaultQuality(opt.value)}
              >
                <Text style={[styles.chipText, active && styles.chipTextActive]}>
                  {opt.label}
                </Text>
              </Pressable>
            );
          })}
        </View>
      </View>

      <View style={styles.section}>
        <Text style={styles.sectionTitle}>About</Text>
        <View style={styles.row}>
          <View style={{ flex: 1 }}>
            <Text style={styles.label}>Version</Text>
            <Text style={styles.hint}>Current JS bundle (OTA-updated)</Text>
          </View>
          <Text style={styles.versionValue}>{APP_VERSION}</Text>
        </View>
        <Pressable
          style={styles.row}
          onPress={() => Linking.openURL(REPO_URL).catch(() => {})}
        >
          <View style={{ flex: 1 }}>
            <Text style={styles.label}>Source code</Text>
            <Text style={styles.hint}>Open source (MIT) — audit it or self-host</Text>
          </View>
          <Text style={styles.linkValue}>{REPO_LABEL} ›</Text>
        </Pressable>
        <Pressable style={styles.row} onPress={() => replayOnboarding()}>
          <View style={{ flex: 1 }}>
            <Text style={styles.label}>Replay tutorial</Text>
            <Text style={styles.hint}>Show the first-launch tour again</Text>
          </View>
          <Text style={styles.linkValue}>›</Text>
        </Pressable>
      </View>
    </ScrollView>
  );
}

// Publiczne repo OSS (zgłoszenie usera 4c5066b8: "no source code repo linked").
// Sygnał zaufania dla sideloadowanej apki 18+: audyt kodu / self-host / kontrybucja.
// Self-hosted Forgejo (git.goon-foss.org) — GitHub goon-foss/goon was soft-banned
// (flag abuse on the resolve-stream language, not DMCA; appeal ignored). Self-host =
// zero ban risk + fits the project's self-hosted ethos. Migrated 2026-06-26.
const REPO_URL = 'https://git.goon-foss.org/goon-foss/goon';
const REPO_LABEL = 'git.goon-foss.org';

const styles = StyleSheet.create({
  root: { flex: 1, backgroundColor: theme.bg },
  center: { flex: 1, backgroundColor: theme.bg, alignItems: 'center', justifyContent: 'center' },
  section: {
    backgroundColor: theme.card,
    marginHorizontal: 14,
    marginTop: 14,
    padding: 16,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: theme.border,
  },
  sectionTitle: {
    color: theme.fg,
    fontSize: 13,
    fontWeight: '700',
    textTransform: 'uppercase',
    letterSpacing: 0.5,
    marginBottom: 10,
  },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 8,
  },
  label: { color: theme.fg, fontSize: 15, fontWeight: '600' },
  hint: { color: theme.muted, fontSize: 12, marginTop: 2 },
  actionBtn: {
    marginTop: 12,
    paddingVertical: 12,
    paddingHorizontal: 16,
    borderRadius: 10,
    backgroundColor: theme.bgElevated,
    borderWidth: 1,
    borderColor: theme.border,
    alignItems: 'center',
  },
  actionText: { color: theme.accent, fontSize: 14, fontWeight: '600' },
  chipRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginTop: 10 },
  chip: {
    paddingVertical: 8,
    paddingHorizontal: 14,
    borderRadius: 999,
    backgroundColor: theme.bgElevated,
    borderWidth: 1,
    borderColor: theme.border,
  },
  chipActive: { backgroundColor: theme.accent, borderColor: theme.accent },
  versionValue: { color: theme.fg, fontSize: 15, fontWeight: '700', fontVariant: ['tabular-nums'] },
  linkValue: { color: theme.accent, fontSize: 15, fontWeight: '700' },
  chipText: { color: theme.muted, fontSize: 13 },
  chipTextActive: { color: '#fff', fontWeight: '700' },
});
