/**
 * Settings screen — sub-route, открывается по tap'у на profile-avatar в
 * TabHeader. Использует обычный `<Header>` с back-кнопкой.
 *
 * Секции:
 *   1. Профиль — avatar, @username, short-address, Copy row.
 *   2. Username — регистрация в native:username_registry (если не куплено).
 *   3. Node — URL + contract ID + Save + Status.
 *   4. Account — Export key, Delete account.
 *
 * Весь Pressable'овый layout живёт на ВНЕШНЕМ View с static style —
 * Pressable handle-ит только background change (через вложенный View
 * в ({pressed}) callback'е), никаких layout props в callback-style.
 * Это лечит web-баг, где Pressable style-функция не применяет
 * percentage/padding layout надёжно.
 */
import React, { useState, useEffect } from 'react';
import {
  View, Text, ScrollView, TextInput, Alert, Pressable, ActivityIndicator, Share,
} from 'react-native';
import * as Clipboard from 'expo-clipboard';
import { router } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { useStore } from '@/lib/store';
import { saveSettings, deleteKeyFile } from '@/lib/storage';
import {
  setNodeUrl, getNetStats, resolveUsername, reverseResolve,
  buildCallContractTx, submitTx,
  USERNAME_REGISTRATION_FEE, MIN_USERNAME_LENGTH, MAX_USERNAME_LENGTH,
  humanizeTxError,
} from '@/lib/api';
import { shortAddr } from '@/lib/crypto';
import { formatAmount, safeBack } from '@/lib/utils';

import { Avatar } from '@/components/Avatar';
import { Header } from '@/components/Header';
import { IconButton } from '@/components/IconButton';

type NodeStatus = 'idle' | 'checking' | 'ok' | 'error';
type IoniconName = React.ComponentProps<typeof Ionicons>['name'];

// ─── Shared layout primitives ─────────────────────────────────────

function SectionLabel({ children }: { children: string }) {
  return (
    <Text
      style={{
        color: '#5a5a5a',
        fontSize: 11,
        letterSpacing: 1.2,
        textTransform: 'uppercase',
        marginTop: 18,
        marginBottom: 8,
        paddingHorizontal: 14,
        fontWeight: '700',
      }}
    >
      {children}
    </Text>
  );
}

function Card({ children }: { children: React.ReactNode }) {
  return (
    <View
      style={{
        backgroundColor: '#0a0a0a',
        borderRadius: 14,
        marginHorizontal: 14,
        overflow: 'hidden',
        borderWidth: 1,
        borderColor: '#1f1f1f',
      }}
    >
      {children}
    </View>
  );
}

/**
 * Row — clickable / non-clickable list item внутри Card'а.
 *
 * Layout живёт на ВНЕШНЕМ контейнере (View если read-only, Pressable
 * если tappable). Для pressed-стейта используется вложенный `<View>`
 * с background-color, чтобы не полагаться на style-функцию Pressable'а
 * (web-баг).
 */
function Row({
  icon, label, value, onPress, right, danger, first,
}: {
  icon:    IoniconName;
  label:   string;
  value?:  string;
  onPress?: () => void;
  right?:   React.ReactNode;
  danger?:  boolean;
  first?:   boolean;
}) {
  const body = (pressed: boolean) => (
    <View
      style={{
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 14,
        paddingVertical: 13,
        backgroundColor: pressed ? '#151515' : 'transparent',
        borderTopWidth: first ? 0 : 1,
        borderTopColor: '#1f1f1f',
      }}
    >
      <View
        style={{
          width: 32,
          height: 32,
          borderRadius: 8,
          backgroundColor: danger ? 'rgba(244,33,46,0.12)' : '#1a1a1a',
          alignItems: 'center',
          justifyContent: 'center',
          marginRight: 12,
        }}
      >
        <Ionicons name={icon} size={16} color={danger ? '#f4212e' : '#ffffff'} />
      </View>
      <View style={{ flex: 1, minWidth: 0 }}>
        <Text
          style={{
            color: danger ? '#f4212e' : '#ffffff',
            fontSize: 14,
            fontWeight: '600',
          }}
        >
          {label}
        </Text>
        {value !== undefined && (
          <Text numberOfLines={1} style={{ color: '#8b8b8b', fontSize: 12, marginTop: 2 }}>
            {value}
          </Text>
        )}
      </View>
      {right}
      {onPress && !right && (
        <Ionicons name="chevron-forward" size={16} color="#5a5a5a" />
      )}
    </View>
  );

  if (!onPress) return <View>{body(false)}</View>;
  return (
    <Pressable onPress={onPress}>
      {({ pressed }) => body(pressed)}
    </Pressable>
  );
}

// ─── Screen ───────────────────────────────────────────────────────

export default function SettingsScreen() {
  const insets     = useSafeAreaInsets();
  const keyFile    = useStore(s => s.keyFile);
  const setKeyFile = useStore(s => s.setKeyFile);
  const settings   = useStore(s => s.settings);
  const setSettings = useStore(s => s.setSettings);
  const username   = useStore(s => s.username);
  const setUsername = useStore(s => s.setUsername);
  const balance    = useStore(s => s.balance);

  const [nodeUrl,     setNodeUrlInput] = useState(settings.nodeUrl);
  const [contractId,  setContractId]   = useState(settings.contractId);
  const [nodeStatus,  setNodeStatus]   = useState<NodeStatus>('idle');
  const [peerCount,   setPeerCount]    = useState<number | null>(null);
  const [blockCount,  setBlockCount]   = useState<number | null>(null);
  const [copied,      setCopied]       = useState(false);
  const [savingNode,  setSavingNode]   = useState(false);

  // Username registration state
  const [nameInput,   setNameInput]    = useState('');
  const [nameError,   setNameError]    = useState<string | null>(null);
  const [registering, setRegistering]  = useState(false);

  useEffect(() => { checkNode(); }, []);
  useEffect(() => { setContractId(settings.contractId); }, [settings.contractId]);
  useEffect(() => {
    if (!settings.contractId || !keyFile) { setUsername(null); return; }
    (async () => {
      const name = await reverseResolve(settings.contractId, keyFile.pub_key);
      setUsername(name);
    })();
  }, [settings.contractId, keyFile, setUsername]);

  async function checkNode() {
    setNodeStatus('checking');
    try {
      const stats = await getNetStats();
      setNodeStatus('ok');
      setPeerCount(stats.peer_count);
      setBlockCount(stats.total_blocks);
    } catch {
      setNodeStatus('error');
    }
  }

  async function saveNode() {
    setSavingNode(true);
    const url = nodeUrl.trim().replace(/\/$/, '');
    setNodeUrl(url);
    const next = { nodeUrl: url, contractId: contractId.trim() };
    setSettings(next);
    await saveSettings(next);
    await checkNode();
    setSavingNode(false);
    Alert.alert('Saved', 'Node settings updated.');
  }

  async function copyAddress() {
    if (!keyFile) return;
    await Clipboard.setStringAsync(keyFile.pub_key);
    setCopied(true);
    setTimeout(() => setCopied(false), 1800);
  }

  async function exportKey() {
    if (!keyFile) return;
    try {
      await Share.share({
        message: JSON.stringify(keyFile, null, 2),
        title:   'DChain key file',
      });
    } catch (e: any) {
      Alert.alert('Export failed', e?.message ?? 'Unknown error');
    }
  }

  function logout() {
    Alert.alert(
      'Delete account',
      'Your key will be removed from this device. Make sure you have a backup!',
      [
        { text: 'Cancel', style: 'cancel' },
        {
          text: 'Delete',
          style: 'destructive',
          onPress: async () => {
            await deleteKeyFile();
            setKeyFile(null);
            router.replace('/');
          },
        },
      ],
    );
  }

  const onNameChange = (v: string) => {
    const cleaned = v.toLowerCase().replace(/[^a-z0-9_\-]/g, '').slice(0, MAX_USERNAME_LENGTH);
    setNameInput(cleaned);
    setNameError(null);
  };
  const nameIsValid = nameInput.length >= MIN_USERNAME_LENGTH && /^[a-z]/.test(nameInput);

  async function registerUsername() {
    if (!keyFile) return;
    const name = nameInput.trim();
    if (!nameIsValid) {
      setNameError(`Min ${MIN_USERNAME_LENGTH} chars, starts with a-z`);
      return;
    }
    if (!settings.contractId) {
      setNameError('No registry contract in node settings');
      return;
    }
    const total = USERNAME_REGISTRATION_FEE + 1000 + 2000;
    if (balance < total) {
      setNameError(`Need ${formatAmount(total)}, have ${formatAmount(balance)}`);
      return;
    }
    try {
      const existing = await resolveUsername(settings.contractId, name);
      if (existing) { setNameError(`@${name} already taken`); return; }
    } catch { /* ignore */ }

    Alert.alert(
      `Buy @${name}?`,
      `Cost: ${formatAmount(USERNAME_REGISTRATION_FEE)} + fee ${formatAmount(1000)}.\nBinds to your address until released.`,
      [
        { text: 'Cancel', style: 'cancel' },
        {
          text: 'Buy',
          onPress: async () => {
            setRegistering(true);
            setNameError(null);
            try {
              const tx = buildCallContractTx({
                from:       keyFile.pub_key,
                contractId: settings.contractId,
                method:     'register',
                args:       [name],
                amount:     USERNAME_REGISTRATION_FEE,
                privKey:    keyFile.priv_key,
              });
              await submitTx(tx);
              setNameInput('');
              Alert.alert('Submitted', 'Registration tx accepted. Name appears in a few seconds.');
              let attempts = 0;
              const iv = setInterval(async () => {
                attempts++;
                const got = keyFile
                  ? await reverseResolve(settings.contractId, keyFile.pub_key)
                  : null;
                if (got) { setUsername(got); clearInterval(iv); }
                else if (attempts >= 10) clearInterval(iv);
              }, 2000);
            } catch (e: any) {
              setNameError(humanizeTxError(e));
            } finally {
              setRegistering(false);
            }
          },
        },
      ],
    );
  }

  const statusColor =
    nodeStatus === 'ok'    ? '#3ba55d' :
    nodeStatus === 'error' ? '#f4212e' :
                             '#f0b35a';
  const statusLabel =
    nodeStatus === 'ok'    ? 'Connected'     :
    nodeStatus === 'error' ? 'Unreachable'   :
                             'Checking…';

  return (
    <View style={{ flex: 1, backgroundColor: '#000000', paddingTop: insets.top }}>
      <Header
        title="Settings"
        divider={false}
        left={<IconButton icon="chevron-back" size={36} onPress={() => safeBack()} />}
      />
      <ScrollView
        contentContainerStyle={{ paddingBottom: 120 }}
        showsVerticalScrollIndicator={false}
      >
        {/* ── Profile ── */}
        <SectionLabel>Profile</SectionLabel>
        <Card>
          <View
            style={{
              flexDirection: 'row',
              alignItems: 'center',
              padding: 14,
              gap: 14,
            }}
          >
            <Avatar
              name={username ?? keyFile?.pub_key ?? '?'}
              address={keyFile?.pub_key}
              size={56}
            />
            <View style={{ flex: 1, minWidth: 0 }}>
              {username ? (
                <View style={{ flexDirection: 'row', alignItems: 'center' }}>
                  <Text style={{ color: '#ffffff', fontWeight: '700', fontSize: 17 }}>
                    @{username}
                  </Text>
                  <Ionicons name="checkmark-circle" size={15} color="#1d9bf0" style={{ marginLeft: 4 }} />
                </View>
              ) : (
                <Text style={{ color: '#8b8b8b', fontSize: 14 }}>No username yet</Text>
              )}
              <Text
                style={{
                  color: '#8b8b8b',
                  fontSize: 11,
                  marginTop: 2,
                  fontFamily: 'monospace',
                }}
                numberOfLines={1}
              >
                {keyFile ? shortAddr(keyFile.pub_key, 10) : '—'}
              </Text>
            </View>
          </View>
          <Row
            icon={copied ? 'checkmark-outline' : 'copy-outline'}
            label={copied ? 'Copied!' : 'Copy address'}
            onPress={copyAddress}
            right={<View style={{ width: 16 }} />}
          />
        </Card>

        {/* ── Username (только если ещё нет) ── */}
        {!username && (
          <>
            <SectionLabel>Username</SectionLabel>
            <Card>
              <View style={{ padding: 14 }}>
                <Text style={{ color: '#ffffff', fontWeight: '600', fontSize: 14, marginBottom: 4 }}>
                  Buy a username
                </Text>
                <Text style={{ color: '#8b8b8b', fontSize: 12, lineHeight: 17, marginBottom: 10 }}>
                  Flat {formatAmount(USERNAME_REGISTRATION_FEE)} fee + {formatAmount(1000)} network.
                  Only a-z, 0-9, _, -. Starts with a letter.
                </Text>

                <View
                  style={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    backgroundColor: '#000000',
                    borderRadius: 10,
                    paddingHorizontal: 12,
                    paddingVertical: 4,
                    borderWidth: 1,
                    borderColor: nameError ? '#f4212e' : '#1f1f1f',
                  }}
                >
                  <Text style={{ color: '#5a5a5a', fontSize: 15, marginRight: 2 }}>@</Text>
                  <TextInput
                    value={nameInput}
                    onChangeText={onNameChange}
                    placeholder="alice"
                    placeholderTextColor="#5a5a5a"
                    autoCapitalize="none"
                    autoCorrect={false}
                    maxLength={MAX_USERNAME_LENGTH}
                    style={{
                      flex: 1,
                      color: '#ffffff',
                      fontSize: 15,
                      paddingVertical: 8,
                    }}
                  />
                </View>
                {nameError && (
                  <Text style={{ color: '#f4212e', fontSize: 12, marginTop: 6 }}>
                    {nameError}
                  </Text>
                )}

                <PrimaryButton
                  onPress={registerUsername}
                  disabled={registering || !nameIsValid || !settings.contractId}
                  loading={registering}
                  label={`Buy @${nameInput || 'username'}`}
                  style={{ marginTop: 12 }}
                />
              </View>
            </Card>
          </>
        )}

        {/* ── Node ── */}
        <SectionLabel>Node</SectionLabel>
        <Card>
          <View style={{ padding: 14, gap: 10 }}>
            <LabeledInput
              label="Node URL"
              value={nodeUrl}
              onChangeText={setNodeUrlInput}
              placeholder="http://localhost:8080"
            />
            <LabeledInput
              label="Username contract"
              value={contractId}
              onChangeText={setContractId}
              placeholder="auto-discovered via /api/well-known-contracts"
              monospace
            />
            <PrimaryButton
              onPress={saveNode}
              disabled={savingNode}
              loading={savingNode}
              label="Save"
              style={{ marginTop: 4 }}
            />
          </View>

          <Row
            icon="pulse-outline"
            label="Status"
            value={
              nodeStatus === 'ok'
                ? `${statusLabel} · ${blockCount ?? 0} blocks · ${peerCount ?? 0} peers`
                : statusLabel
            }
            right={
              <View
                style={{ width: 8, height: 8, borderRadius: 4, backgroundColor: statusColor }}
              />
            }
          />
        </Card>

        {/* ── Devices — multi-device registry (v2.2.0) ── */}
        <SectionLabel>Devices</SectionLabel>
        <Card>
          <Row
            icon="phone-portrait-outline"
            label="Linked devices"
            value="Manage the devices that receive your messages"
            onPress={() => router.push('/(app)/devices' as never)}
            first
          />
        </Card>

        {/* ── Account ── */}
        <SectionLabel>Account</SectionLabel>
        <Card>
          <Row
            icon="download-outline"
            label="Export key"
            value="Save your private key as JSON"
            onPress={exportKey}
            first
          />
          <Row
            icon="trash-outline"
            label="Delete account"
            value="Remove key from this device"
            onPress={logout}
            danger
          />
        </Card>
      </ScrollView>
    </View>
  );
}

// ─── Form primitives ──────────────────────────────────────────────

function LabeledInput({
  label, value, onChangeText, placeholder, monospace,
}: {
  label:        string;
  value:        string;
  onChangeText: (v: string) => void;
  placeholder?: string;
  monospace?:   boolean;
}) {
  return (
    <View>
      <Text style={{ color: '#8b8b8b', fontSize: 12, marginBottom: 6 }}>{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChangeText}
        placeholder={placeholder}
        placeholderTextColor="#5a5a5a"
        autoCapitalize="none"
        autoCorrect={false}
        style={{
          color: '#ffffff',
          fontSize: monospace ? 13 : 14,
          fontFamily: monospace ? 'monospace' : undefined,
          backgroundColor: '#000000',
          borderRadius: 10,
          paddingHorizontal: 12,
          paddingVertical: 10,
          borderWidth: 1,
          borderColor: '#1f1f1f',
        }}
      />
    </View>
  );
}

function PrimaryButton({
  label, onPress, disabled, loading, style,
}: {
  label: string;
  onPress: () => void;
  disabled?: boolean;
  loading?: boolean;
  style?: object;
}) {
  return (
    <Pressable onPress={onPress} disabled={disabled} style={style}>
      {({ pressed }) => (
        <View
          style={{
            alignItems: 'center',
            justifyContent: 'center',
            paddingVertical: 11,
            borderRadius: 999,
            backgroundColor: disabled
              ? '#1a1a1a'
              : pressed ? '#1a8cd8' : '#1d9bf0',
          }}
        >
          {loading ? (
            <ActivityIndicator color="#ffffff" size="small" />
          ) : (
            <Text
              style={{
                color: disabled ? '#5a5a5a' : '#ffffff',
                fontWeight: '700',
                fontSize: 14,
              }}
            >
              {label}
            </Text>
          )}
        </View>
      )}
    </Pressable>
  );
}
