/**
 * Onboarding — 3-слайдовый pager перед auth-экранами.
 *
 * Slide 1 — "Why DChain": value-proposition, 3 пункта с иконками.
 * Slide 2 — "How it works": выбор релей-ноды (public paid vs свой node),
 *           ссылка на Gitea, + node URL input с live ping.
 * Slide 3 — "Your keys": кнопки Create / Import.
 *
 * Если `keyFile` в store уже есть (bootstrap из RootLayout загрузил) —
 * делаем <Redirect /> в (app), чтобы пользователь не видел вообще никакого
 * мелькания onboarding'а. До загрузки `booted === false` root показывает
 * чёрный экран.
 */
import React, { useEffect, useState, useCallback, useRef } from 'react';
import {
  View, Text, TextInput, Pressable, ScrollView,
  Alert, ActivityIndicator, Linking, Dimensions,
  useWindowDimensions,
} from 'react-native';
import { router, Redirect } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { CameraView, useCameraPermissions } from 'expo-camera';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useStore } from '@/lib/store';
import { saveSettings } from '@/lib/storage';
import { setNodeUrl, getNetStats } from '@/lib/api';

const { width: SCREEN_W } = Dimensions.get('window');
const GITEA_URL = 'https://git.vsecoder.vodka/vsecoder/dchain';

export default function WelcomeScreen() {
  const insets      = useSafeAreaInsets();
  const { height: SCREEN_H } = useWindowDimensions();
  const keyFile     = useStore(s => s.keyFile);
  const booted      = useStore(s => s.booted);
  const settings    = useStore(s => s.settings);
  const setSettings = useStore(s => s.setSettings);

  const scrollRef = useRef<ScrollView>(null);
  const [page, setPage]           = useState(0);
  const [nodeInput, setNodeInput] = useState('');
  const [scanning,  setScanning]  = useState(false);
  const [checking,  setChecking]  = useState(false);
  const [nodeOk,    setNodeOk]    = useState<boolean | null>(null);

  const [permission, requestPermission] = useCameraPermissions();

  useEffect(() => { setNodeInput(settings.nodeUrl); }, [settings.nodeUrl]);

  // ВСЕ hooks должны быть объявлены ДО любого early-return, иначе
  // React на следующем render'е посчитает разное число hooks и выкинет
  // "Rendered fewer hooks than expected". useCallback ниже — тоже hook.
  const applyNode = useCallback(async (url: string) => {
    const clean = url.trim().replace(/\/$/, '');
    if (!clean) return;
    setChecking(true);
    setNodeOk(null);
    setNodeUrl(clean);
    try {
      await getNetStats();
      setNodeOk(true);
      const next = { ...settings, nodeUrl: clean };
      setSettings(next);
      await saveSettings(next);
    } catch {
      setNodeOk(false);
    } finally {
      setChecking(false);
    }
  }, [settings, setSettings]);

  const onQrScanned = useCallback(({ data }: { data: string }) => {
    setScanning(false);
    let url = data.trim();
    try { const p = JSON.parse(url); if (p.nodeUrl) url = p.nodeUrl; } catch {}
    setNodeInput(url);
    applyNode(url);
  }, [applyNode]);

  // Bootstrap ещё не закончился — ничего не рендерим, RootLayout покажет
  // чёрный экран (single source of truth для splash-state'а).
  if (!booted) return null;

  // Ключи уже загружены — сразу в main app, без мелькания onboarding'а.
  if (keyFile) return <Redirect href={'/(app)/chats' as never} />;

  const openScanner = async () => {
    if (!permission?.granted) {
      const { granted } = await requestPermission();
      if (!granted) {
        Alert.alert('Camera permission required', 'Allow camera access to scan QR codes.');
        return;
      }
    }
    setScanning(true);
  };

  const goToPage = (p: number) => {
    scrollRef.current?.scrollTo({ x: p * SCREEN_W, animated: true });
    setPage(p);
  };

  if (scanning) {
    return (
      <View style={{ flex: 1, backgroundColor: '#000' }}>
        <CameraView
          style={{ flex: 1 }}
          facing="back"
          barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
          onBarcodeScanned={onQrScanned}
        />
        <View style={{
          position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,
          alignItems: 'center', justifyContent: 'center',
        }}>
          <View style={{ width: 240, height: 240, borderWidth: 2, borderColor: '#fff', borderRadius: 16 }} />
          <Text style={{ color: '#fff', marginTop: 20, opacity: 0.8 }}>
            Point at a DChain node QR code
          </Text>
        </View>
        <Pressable
          onPress={() => setScanning(false)}
          style={{
            position: 'absolute', top: 56, left: 16,
            backgroundColor: 'rgba(0,0,0,0.6)', borderRadius: 20,
            paddingHorizontal: 16, paddingVertical: 8,
          }}
        >
          <Text style={{ color: '#fff', fontSize: 16 }}>✕  Cancel</Text>
        </Pressable>
      </View>
    );
  }

  const statusColor = nodeOk === true ? '#3ba55d' : nodeOk === false ? '#f4212e' : '#8b8b8b';

  // Высота footer'а (dots + inset) — резервируем под неё снизу каждого
  // слайда, чтобы CTA-кнопки оказывались прямо над индикатором страниц,
  // а не залезали под него.
  const FOOTER_H = Math.max(insets.bottom, 20) + 8 + 12 + 7; // = padBottom + padTop + dot
  const PAGE_H   = SCREEN_H - FOOTER_H;

  return (
    <View style={{ flex: 1, backgroundColor: '#000000' }}>
      <ScrollView
        ref={scrollRef}
        horizontal
        pagingEnabled
        showsHorizontalScrollIndicator={false}
        onMomentumScrollEnd={e => {
          const p = Math.round(e.nativeEvent.contentOffset.x / SCREEN_W);
          setPage(p);
        }}
        style={{ flex: 1 }}
        keyboardShouldPersistTaps="handled"
      >
        {/* ───────── Slide 1: Why DChain ───────── */}
        <View style={{ width: SCREEN_W, height: PAGE_H }}>
          <ScrollView
            style={{ flex: 1 }}
            contentContainerStyle={{
              paddingHorizontal: 28,
              paddingTop: insets.top + 60,
              paddingBottom: 16,
            }}
            showsVerticalScrollIndicator={false}
          >
            <View style={{ alignItems: 'center', marginBottom: 36 }}>
              <View
                style={{
                  width: 88, height: 88, borderRadius: 24,
                  backgroundColor: '#1d9bf0',
                  alignItems: 'center', justifyContent: 'center',
                  marginBottom: 14,
                }}
              >
                <Ionicons name="chatbubbles" size={44} color="#ffffff" />
              </View>
              <Text style={{ color: '#ffffff', fontSize: 30, fontWeight: '800', letterSpacing: -0.8 }}>
                DChain
              </Text>
              <Text style={{ color: '#8b8b8b', textAlign: 'center', fontSize: 14, lineHeight: 20, marginTop: 6 }}>
                A messenger that belongs to you.
              </Text>
            </View>

            <FeatureRow
              icon="lock-closed"
              title="End-to-end encryption"
              text="X25519 + NaCl на каждом сообщении. Даже релей-нода не может прочитать переписку."
            />
            <FeatureRow
              icon="key"
              title="Твои ключи — твой аккаунт"
              text="Без телефона, email и серверных паролей. Ключи никогда не покидают устройство."
            />
            <FeatureRow
              icon="git-network"
              title="Decentralised"
              text="Любой может поднять свою ноду. Нет единой точки отказа и цензуры."
            />
          </ScrollView>

          {/* CTA — прижата к правому нижнему краю. */}
          <View style={{
            flexDirection: 'row', justifyContent: 'flex-end',
            paddingHorizontal: 24, paddingBottom: 8,
          }}>
            <CTAPrimary label="Продолжить" onPress={() => goToPage(1)} />
          </View>
        </View>

        {/* ───────── Slide 2: How it works ───────── */}
        <View style={{ width: SCREEN_W, height: PAGE_H }}>
          <ScrollView
            style={{ flex: 1 }}
            contentContainerStyle={{
              paddingHorizontal: 28,
              paddingTop: insets.top + 40,
              paddingBottom: 16,
            }}
            showsVerticalScrollIndicator={false}
            keyboardShouldPersistTaps="handled"
          >
          <Text style={{ color: '#ffffff', fontSize: 24, fontWeight: '800', letterSpacing: -0.5 }}>
            Как это работает
          </Text>
          <Text style={{ color: '#8b8b8b', fontSize: 14, lineHeight: 20, marginTop: 8, marginBottom: 22 }}>
            Сообщения проходят через релей-ноду в зашифрованном виде.
            Выбери публичную или подключи свою.
          </Text>

          <OptionCard
            icon="globe"
            title="Публичная нода"
            text="Удобно и быстро — нода хостится комьюнити, небольшая комиссия за каждое отправленное сообщение."
          />
          <OptionCard
            icon="hardware-chip"
            title="Своя нода"
            text="Максимальный контроль. Исходники открыты — подними на своём сервере за 5 минут."
          />

          <Text style={{
            color: '#5a5a5a', fontSize: 11, fontWeight: '700',
            textTransform: 'uppercase', letterSpacing: 1.2, marginTop: 20, marginBottom: 8,
          }}>
            Node URL
          </Text>
          <View style={{ flexDirection: 'row', gap: 8 }}>
            <View
              style={{
                flex: 1, flexDirection: 'row', alignItems: 'center',
                backgroundColor: '#0a0a0a', borderWidth: 1, borderColor: '#1f1f1f',
                borderRadius: 12, paddingHorizontal: 12, gap: 8,
              }}
            >
              <View style={{ width: 7, height: 7, borderRadius: 3.5, backgroundColor: statusColor }} />
              <TextInput
                value={nodeInput}
                onChangeText={t => { setNodeInput(t); setNodeOk(null); }}
                onEndEditing={() => applyNode(nodeInput)}
                onSubmitEditing={() => applyNode(nodeInput)}
                placeholder="http://192.168.1.10:8080"
                placeholderTextColor="#5a5a5a"
                autoCapitalize="none"
                autoCorrect={false}
                keyboardType="url"
                returnKeyType="done"
                style={{ flex: 1, color: '#ffffff', fontSize: 14, paddingVertical: 12 }}
              />
              {checking
                ? <ActivityIndicator size="small" color="#8b8b8b" />
                : nodeOk === true
                  ? <Ionicons name="checkmark" size={16} color="#3ba55d" />
                  : nodeOk === false
                    ? <Ionicons name="close" size={16} color="#f4212e" />
                    : null}
            </View>
            <Pressable
              onPress={openScanner}
              style={({ pressed }) => ({
                width: 48, alignItems: 'center', justifyContent: 'center',
                backgroundColor: pressed ? '#1a1a1a' : '#0a0a0a',
                borderWidth: 1, borderColor: '#1f1f1f',
                borderRadius: 12,
              })}
            >
              <Ionicons name="qr-code-outline" size={22} color="#ffffff" />
            </Pressable>
          </View>
          {nodeOk === false && (
            <Text style={{ color: '#f4212e', fontSize: 12, marginTop: 6 }}>
              Cannot reach node — check URL and that the node is running
            </Text>
          )}
          </ScrollView>

          {/* CTA — прижата к правому нижнему краю. */}
          <View style={{
            flexDirection: 'row', justifyContent: 'flex-end', gap: 10,
            paddingHorizontal: 24, paddingBottom: 8,
          }}>
            <CTASecondary
              label="Исходники"
              icon="logo-github"
              onPress={() => Linking.openURL(GITEA_URL).catch(() => {})}
            />
            <CTAPrimary label="Продолжить" onPress={() => goToPage(2)} />
          </View>
        </View>

        {/* ───────── Slide 3: Your keys ───────── */}
        <View style={{ width: SCREEN_W, height: PAGE_H }}>
          <ScrollView
            style={{ flex: 1 }}
            contentContainerStyle={{
              paddingHorizontal: 28,
              paddingTop: insets.top + 60,
              paddingBottom: 16,
            }}
            showsVerticalScrollIndicator={false}
          >
            <View style={{ alignItems: 'center', marginBottom: 36 }}>
              <View
                style={{
                  width: 88, height: 88, borderRadius: 24,
                  backgroundColor: '#0a0a0a',
                  borderWidth: 1, borderColor: '#1f1f1f',
                  alignItems: 'center', justifyContent: 'center',
                  marginBottom: 16,
                }}
              >
                <Ionicons name="key" size={44} color="#1d9bf0" />
              </View>
              <Text style={{ color: '#ffffff', fontSize: 24, fontWeight: '800', letterSpacing: -0.5, textAlign: 'center' }}>
                Твой аккаунт
              </Text>
              <Text style={{ color: '#8b8b8b', fontSize: 14, lineHeight: 20, marginTop: 8, textAlign: 'center', maxWidth: 280 }}>
                Создай новую пару ключей или импортируй существующую.
                Ключи хранятся только на этом устройстве.
              </Text>
            </View>
          </ScrollView>

          {/* CTA — прижата к правому нижнему краю. */}
          <View style={{
            flexDirection: 'row', justifyContent: 'flex-end', gap: 10,
            paddingHorizontal: 24, paddingBottom: 8,
          }}>
            <CTASecondary
              label="Импорт"
              onPress={() => router.push('/(auth)/import' as never)}
            />
            <CTAPrimary
              label="Создать аккаунт"
              onPress={() => router.push('/(auth)/create' as never)}
            />
          </View>
        </View>
      </ScrollView>

      {/* Footer: dots-only pager indicator. CTA-кнопки теперь inline
          на каждом слайде, чтобы выглядели как полноценные кнопки, а не
          мелкий "Далее" в углу. */}
      <View style={{
        paddingHorizontal: 28,
        paddingBottom: Math.max(insets.bottom, 20) + 8,
        paddingTop: 12,
        flexDirection: 'row',
        alignItems: 'center', justifyContent: 'center',
        gap: 6,
      }}>
        {[0, 1, 2].map(i => (
          <Pressable
            key={i}
            onPress={() => goToPage(i)}
            hitSlop={8}
            style={{
              width:  page === i ? 22 : 7,
              height: 7,
              borderRadius: 3.5,
              backgroundColor: page === i ? '#1d9bf0' : '#2a2a2a',
            }}
          />
        ))}
      </View>
    </View>
  );
}

// ───────── helper components ─────────

/**
 * Primary CTA button — синий pill. Натуральная ширина (hugs content),
 * `numberOfLines={1}` на лейбле чтобы текст не переносился. Фон
 * применяется через inner View, а не напрямую на Pressable — это
 * обходит редкие RN-баги, когда backgroundColor на Pressable не
 * рендерится пока кнопка не нажата.
 */
function CTAPrimary({ label, onPress }: { label: string; onPress: () => void }) {
  return (
    <Pressable onPress={onPress} style={({ pressed }) => ({ opacity: pressed ? 0.85 : 1 })}>
      <View
        style={{
          height: 46,
          paddingHorizontal: 22,
          borderRadius: 999,
          backgroundColor: '#1d9bf0',
          alignItems: 'center', justifyContent: 'center',
        }}
      >
        <Text
          numberOfLines={1}
          style={{ color: '#ffffff', fontWeight: '700', fontSize: 15 }}
        >
          {label}
        </Text>
      </View>
    </Pressable>
  );
}

/** Secondary CTA — тёмный pill с border'ом, optional icon слева. */
function CTASecondary({
  label, icon, onPress,
}: {
  label: string;
  icon?: React.ComponentProps<typeof Ionicons>['name'];
  onPress: () => void;
}) {
  return (
    <Pressable onPress={onPress} style={({ pressed }) => ({ opacity: pressed ? 0.6 : 1 })}>
      <View
        style={{
          height: 46,
          paddingHorizontal: 18,
          borderRadius: 999,
          backgroundColor: '#0a0a0a',
          borderWidth: 1, borderColor: '#1f1f1f',
          flexDirection: 'row', alignItems: 'center', justifyContent: 'center',
          gap: 6,
        }}
      >
        {icon && <Ionicons name={icon} size={15} color="#ffffff" />}
        <Text
          numberOfLines={1}
          style={{ color: '#ffffff', fontWeight: '700', fontSize: 14 }}
        >
          {label}
        </Text>
      </View>
    </Pressable>
  );
}

function FeatureRow({
  icon, title, text,
}: { icon: React.ComponentProps<typeof Ionicons>['name']; title: string; text: string }) {
  return (
    <View style={{ flexDirection: 'row', marginBottom: 20, gap: 14 }}>
      <View
        style={{
          width: 40, height: 40, borderRadius: 12,
          backgroundColor: '#0a0a0a',
          borderWidth: 1, borderColor: '#1f1f1f',
          alignItems: 'center', justifyContent: 'center',
        }}
      >
        <Ionicons name={icon} size={20} color="#1d9bf0" />
      </View>
      <View style={{ flex: 1 }}>
        <Text style={{ color: '#ffffff', fontSize: 15, fontWeight: '700', marginBottom: 3 }}>
          {title}
        </Text>
        <Text style={{ color: '#8b8b8b', fontSize: 13, lineHeight: 19 }}>
          {text}
        </Text>
      </View>
    </View>
  );
}

function OptionCard({
  icon, title, text, actionLabel, onAction,
}: {
  icon: React.ComponentProps<typeof Ionicons>['name'];
  title: string;
  text: string;
  actionLabel?: string;
  onAction?: () => void;
}) {
  return (
    <View
      style={{
        backgroundColor: '#0a0a0a',
        borderWidth: 1, borderColor: '#1f1f1f',
        borderRadius: 14, padding: 14, marginBottom: 10,
      }}
    >
      <View style={{ flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 6 }}>
        <Ionicons name={icon} size={18} color="#1d9bf0" />
        <Text style={{ color: '#ffffff', fontSize: 15, fontWeight: '700' }}>
          {title}
        </Text>
      </View>
      <Text style={{ color: '#8b8b8b', fontSize: 13, lineHeight: 19 }}>
        {text}
      </Text>
      {actionLabel && onAction && (
        <Pressable onPress={onAction} style={({ pressed }) => ({ opacity: pressed ? 0.6 : 1, marginTop: 8 })}>
          <Text style={{ color: '#1d9bf0', fontSize: 13, fontWeight: '600' }}>
            {actionLabel}
          </Text>
        </Pressable>
      )}
    </View>
  );
}
