/**
 * Wallet screen — DChain explorer style.
 * Balance block inspired by Tinkoff/Gravity UI reference.
 * Icons: Ionicons from @expo/vector-icons.
 */

import React, { useState, useCallback, useEffect } from 'react';
import {
  View, Text, ScrollView, Modal, TouchableOpacity,
  Alert, RefreshControl,
} from 'react-native';
import * as Clipboard from 'expo-clipboard';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useStore } from '@/lib/store';
import { useBalance } from '@/hooks/useBalance';
import { buildTransferTx, submitTx, getTxHistory, getBalance } from '@/lib/api';
import { shortAddr } from '@/lib/crypto';
import { formatAmount, relativeTime } from '@/lib/utils';
import { Input } from '@/components/ui/Input';
import type { TxRecord } from '@/lib/types';

// ─── Design tokens ────────────────────────────────────────────────────────────
const C = {
  bg:      '#0b1220',
  surface: '#111a2b',
  surface2:'#162035',
  surface3:'#1a2640',
  line:    '#1c2840',
  text:    '#e6edf9',
  muted:   '#98a7c2',
  accent:  '#7db5ff',
  ok:      '#41c98a',
  warn:    '#f0b35a',
  err:     '#ff7a87',
} as const;

// ─── TX metadata ──────────────────────────────────────────────────────────────

const TX_META: Record<string, { label: string; icon: keyof typeof Ionicons.glyphMap; color: string }> = {
  TRANSFER:        { label: 'Перевод',         icon: 'paper-plane-outline',    color: C.accent },
  CONTACT_REQUEST: { label: 'Запрос контакта', icon: 'person-add-outline',     color: C.ok    },
  ACCEPT_CONTACT:  { label: 'Принят контакт',  icon: 'person-outline',         color: C.ok    },
  BLOCK_CONTACT:   { label: 'Блокировка',      icon: 'ban-outline',            color: C.err   },
  DEPLOY_CONTRACT: { label: 'Деплой контракта',icon: 'document-text-outline',  color: C.warn  },
  CALL_CONTRACT:   { label: 'Вызов контракта', icon: 'flash-outline',          color: C.warn  },
  STAKE:           { label: 'Стейкинг',        icon: 'lock-closed-outline',    color: C.accent},
  UNSTAKE:         { label: 'Вывод стейка',    icon: 'lock-open-outline',      color: C.muted },
  REGISTER_KEY:    { label: 'Регистрация',     icon: 'key-outline',            color: C.muted },
  BLOCK_REWARD:    { label: 'Награда',         icon: 'diamond-outline',        color: C.ok    },
};

function txMeta(type: string) {
  return TX_META[type] ?? { label: type.replace(/_/g, ' '), icon: 'ellipse-outline' as any, color: C.muted };
}

// ─── Component ────────────────────────────────────────────────────────────────

export default function WalletScreen() {
  const keyFile    = useStore(s => s.keyFile);
  const balance    = useStore(s => s.balance);
  const setBalance = useStore(s => s.setBalance);
  const insets     = useSafeAreaInsets();

  useBalance();

  const [txHistory,  setTxHistory]  = useState<TxRecord[]>([]);
  const [refreshing, setRefreshing] = useState(false);
  const [showSend,   setShowSend]   = useState(false);
  const [selectedTx, setSelectedTx] = useState<TxRecord | null>(null);
  const [toAddress,  setToAddress]  = useState('');
  const [amount,     setAmount]     = useState('');
  const [fee,        setFee]        = useState('1000');
  const [sending,    setSending]    = useState(false);
  const [copied,     setCopied]     = useState(false);

  const load = useCallback(async () => {
    if (!keyFile) return;
    setRefreshing(true);
    try {
      const [hist, bal] = await Promise.all([
        getTxHistory(keyFile.pub_key),
        getBalance(keyFile.pub_key),
      ]);
      setTxHistory(hist);
      setBalance(bal);
    } catch {}
    setRefreshing(false);
  }, [keyFile]);

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

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

  const send = async () => {
    if (!keyFile) return;
    const amt = parseInt(amount);
    const f   = parseInt(fee);
    if (!toAddress.trim() || isNaN(amt) || amt <= 0) {
      Alert.alert('Неверные данные', 'Введите корректный адрес и сумму.');
      return;
    }
    if (amt + f > balance) {
      Alert.alert('Недостаточно средств', `Нужно ${formatAmount(amt + f)}, доступно ${formatAmount(balance)}.`);
      return;
    }
    setSending(true);
    try {
      const tx = buildTransferTx({ from: keyFile.pub_key, to: toAddress.trim(), amount: amt, fee: f, privKey: keyFile.priv_key });
      await submitTx(tx);
      setShowSend(false);
      setToAddress('');
      setAmount('');
      Alert.alert('Отправлено', 'Транзакция принята нодой.');
      setTimeout(load, 1500);
    } catch (e: any) {
      Alert.alert('Ошибка', e.message);
    } finally {
      setSending(false);
    }
  };

  return (
    <View style={{ flex: 1, backgroundColor: C.bg }}>
      <ScrollView
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={load} tintColor={C.accent} />}
        contentContainerStyle={{ paddingBottom: 32 }}
      >
        {/* ── Balance hero ── */}
        <BalanceHero
          balance={balance}
          address={keyFile?.pub_key ?? ''}
          copied={copied}
          topInset={insets.top}
          onSend={() => setShowSend(true)}
          onReceive={copyAddress}
          onRefresh={load}
          onCopy={copyAddress}
        />

        {/* ── Transaction list ── */}
        <View style={{ paddingHorizontal: 16, paddingTop: 8 }}>
          <Text style={{ color: C.muted, fontSize: 11, letterSpacing: 1, textTransform: 'uppercase', marginBottom: 10 }}>
            История транзакций
          </Text>

          {txHistory.length === 0 ? (
            <View style={{ backgroundColor: C.surface, borderRadius: 12, paddingVertical: 36, alignItems: 'center' }}>
              <Ionicons name="receipt-outline" size={32} color={C.muted} style={{ marginBottom: 10 }} />
              <Text style={{ color: C.muted, fontSize: 14 }}>Нет транзакций</Text>
              <Text style={{ color: C.muted, fontSize: 12, marginTop: 4 }}>Потяните вниз, чтобы обновить</Text>
            </View>
          ) : (
            <View style={{ backgroundColor: C.surface, borderRadius: 12, overflow: 'hidden' }}>
              {/* Table header */}
              <View style={{
                flexDirection: 'row',
                alignItems: 'center',
                paddingHorizontal: 14,
                paddingVertical: 8,
                borderBottomWidth: 1,
                borderBottomColor: C.line,
              }}>
                <Text style={{ color: C.muted, fontSize: 10, fontWeight: '600', letterSpacing: 0.5, width: 140 }}>
                  ТИП
                </Text>
                <Text style={{ color: C.muted, fontSize: 10, fontWeight: '600', letterSpacing: 0.5, flex: 1 }}>
                  АДРЕС
                </Text>
                <Text style={{ color: C.muted, fontSize: 10, fontWeight: '600', letterSpacing: 0.5, width: 84, textAlign: 'right' }}>
                  СУММА
                </Text>
              </View>

              {txHistory.map((tx, i) => (
                <TxRow
                  key={tx.hash}
                  tx={tx}
                  myPubKey={keyFile?.pub_key ?? ''}
                  isLast={i === txHistory.length - 1}
                  onPress={() => setSelectedTx(tx)}
                />
              ))}
            </View>
          )}
        </View>
      </ScrollView>

      {/* Send modal */}
      <Modal visible={showSend} animationType="slide" presentationStyle="pageSheet" onRequestClose={() => setShowSend(false)}>
        <SendSheet
          balance={balance}
          toAddress={toAddress} setToAddress={setToAddress}
          amount={amount} setAmount={setAmount}
          fee={fee} setFee={setFee}
          sending={sending}
          onSend={send}
          onClose={() => setShowSend(false)}
        />
      </Modal>

      {/* TX Detail modal */}
      <Modal visible={!!selectedTx} animationType="slide" presentationStyle="pageSheet" onRequestClose={() => setSelectedTx(null)}>
        {selectedTx && (
          <TxDetailSheet tx={selectedTx} myPubKey={keyFile?.pub_key ?? ''} onClose={() => setSelectedTx(null)} />
        )}
      </Modal>
    </View>
  );
}

// ─── Balance Hero ─────────────────────────────────────────────────────────────

function BalanceHero({
  balance, address, copied, topInset, onSend, onReceive, onRefresh, onCopy,
}: {
  balance: number; address: string; copied: boolean;
  topInset: number;
  onSend: () => void; onReceive: () => void;
  onRefresh: () => void; onCopy: () => void;
}) {
  return (
    <View style={{
      backgroundColor: C.surface,
      paddingTop: topInset + 16, paddingBottom: 28,
      paddingHorizontal: 20,
      borderBottomLeftRadius: 20,
      borderBottomRightRadius: 20,
      alignItems: 'center',
      marginBottom: 20,
    }}>
      {/* Label */}
      <Text style={{ color: C.muted, fontSize: 13, marginBottom: 8, letterSpacing: 0.3 }}>
        Баланс
      </Text>

      {/* Main balance */}
      <Text style={{ color: C.text, fontSize: 42, fontWeight: '700', letterSpacing: -1, lineHeight: 50 }}>
        {formatAmount(balance)}
      </Text>

      {/* µT sub-label */}
      <Text style={{ color: C.muted, fontSize: 13, marginTop: 4, marginBottom: 20 }}>
        {(balance ?? 0).toLocaleString()} µT
      </Text>

      {/* Address chip */}
      <TouchableOpacity
        onPress={onCopy}
        style={{
          flexDirection: 'row', alignItems: 'center', gap: 6,
          backgroundColor: copied ? 'rgba(65,201,138,0.12)' : C.surface2,
          borderRadius: 999, paddingHorizontal: 12, paddingVertical: 6,
          marginBottom: 24,
        }}
      >
        <Ionicons
          name={copied ? 'checkmark-outline' : 'copy-outline'}
          size={13}
          color={copied ? C.ok : C.muted}
        />
        <Text style={{ color: copied ? C.ok : C.muted, fontSize: 12, fontFamily: 'monospace' }}>
          {copied ? 'Скопировано' : (address ? shortAddr(address, 8) : '—')}
        </Text>
      </TouchableOpacity>

      {/* Action buttons */}
      <View style={{ flexDirection: 'row', gap: 20 }}>
        <ActionButton icon="paper-plane-outline" label="Отправить" color={C.accent} onPress={onSend} />
        <ActionButton icon="arrow-down-circle-outline" label="Получить" color={C.accent} onPress={onReceive} />
        <ActionButton icon="refresh-outline" label="Обновить" color={C.muted} onPress={onRefresh} />
      </View>
    </View>
  );
}

function ActionButton({
  icon, label, color, onPress,
}: {
  icon: keyof typeof Ionicons.glyphMap; label: string; color: string; onPress: () => void;
}) {
  return (
    <TouchableOpacity onPress={onPress} style={{ alignItems: 'center', gap: 8 }}>
      <View style={{
        width: 52, height: 52, borderRadius: 26,
        backgroundColor: C.surface3,
        alignItems: 'center', justifyContent: 'center',
      }}>
        <Ionicons name={icon} size={22} color={color} />
      </View>
      <Text style={{ color: C.muted, fontSize: 12 }}>{label}</Text>
    </TouchableOpacity>
  );
}

// ─── Transaction Row ──────────────────────────────────────────────────────────
// Column widths must match the header above:
//   col1 (type+icon): 140   col2 (address): flex:1   col3 (amount): 84

// tx types where "from" is always the owner but it's income, not a send
const RECEIVED_TYPES = new Set(['BLOCK_REWARD', 'STAKE_REWARD']);

function TxRow({
  tx, myPubKey, isLast, onPress,
}: {
  tx: TxRecord; myPubKey: string; isLast: boolean; onPress: () => void;
}) {
  const meta    = txMeta(tx.type);
  const isSynthetic = !tx.from;                           // block reward / mint
  const isSent  = !isSynthetic && !RECEIVED_TYPES.has(tx.type) && tx.from === myPubKey;
  const amt     = tx.amount ?? 0;
  const amtText = amt === 0 ? '' : `${isSent ? '−' : '+'}${formatAmount(amt)}`;
  const amtColor = isSent ? C.err : C.ok;

  // Counterpart label: for synthetic (empty from) rewards → "Сеть",
  // otherwise show the short address of the other side.
  const counterpart = isSynthetic
    ? 'Сеть'
    : isSent
      ? (tx.to   ? shortAddr(tx.to,  6) : '—')
      : shortAddr(tx.from, 6);

  return (
    <TouchableOpacity
      onPress={onPress}
      activeOpacity={0.6}
      style={{
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 14,
        paddingVertical: 11,
        borderBottomWidth: isLast ? 0 : 1,
        borderBottomColor: C.line,
      }}
    >
      {/* Col 1 — icon + type label, fixed 140px */}
      <View style={{ width: 140, flexDirection: 'row', alignItems: 'center' }}>
        <View style={{
          width: 28, height: 28, borderRadius: 14,
          backgroundColor: `${meta.color}1a`,
          alignItems: 'center', justifyContent: 'center',
          marginRight: 8, flexShrink: 0,
        }}>
          <Ionicons name={meta.icon} size={14} color={meta.color} />
        </View>
        <Text style={{ color: C.text, fontSize: 13, fontWeight: '500', flexShrink: 1 }} numberOfLines={1}>
          {meta.label}
        </Text>
      </View>

      {/* Col 2 — address, flex */}
      <View style={{ flex: 1 }}>
        <Text style={{ color: C.muted, fontSize: 12 }} numberOfLines={1}>
          {isSent ? `→ ${counterpart}` : `← ${counterpart}`}
        </Text>
      </View>

      {/* Col 3 — amount + time, fixed 84px, right-aligned */}
      <View style={{ width: 84, alignItems: 'flex-end' }}>
        {!!amtText && (
          <Text style={{ color: amtColor, fontSize: 12, fontWeight: '600' }} numberOfLines={1}>
            {amtText}
          </Text>
        )}
        <Text style={{ color: C.muted, fontSize: 11, marginTop: amtText ? 1 : 0 }} numberOfLines={1}>
          {relativeTime(tx.timestamp)}
        </Text>
      </View>
    </TouchableOpacity>
  );
}

// ─── Send Sheet ───────────────────────────────────────────────────────────────

function SendSheet({
  balance, toAddress, setToAddress, amount, setAmount, fee, setFee, sending, onSend, onClose,
}: {
  balance: number;
  toAddress: string; setToAddress: (v: string) => void;
  amount: string; setAmount: (v: string) => void;
  fee: string; setFee: (v: string) => void;
  sending: boolean; onSend: () => void; onClose: () => void;
}) {
  return (
    <View style={{ flex: 1, backgroundColor: C.bg, paddingHorizontal: 16, paddingTop: 20 }}>
      <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
        <Text style={{ color: C.text, fontSize: 20, fontWeight: '700' }}>Отправить</Text>
        <TouchableOpacity onPress={onClose} style={{ padding: 8, backgroundColor: C.surface2, borderRadius: 8 }}>
          <Ionicons name="close-outline" size={18} color={C.muted} />
        </TouchableOpacity>
      </View>

      <View style={{
        flexDirection: 'row', alignItems: 'center', gap: 8,
        backgroundColor: C.surface, borderRadius: 8,
        paddingHorizontal: 12, paddingVertical: 10, marginBottom: 20,
      }}>
        <Ionicons name="wallet-outline" size={15} color={C.muted} />
        <Text style={{ color: C.muted, fontSize: 13 }}>Доступно:</Text>
        <Text style={{ color: C.text, fontSize: 13, fontWeight: '600' }}>{formatAmount(balance)}</Text>
      </View>

      <Input label="Адрес получателя" placeholder="64-символьный hex" value={toAddress}
        onChangeText={setToAddress} autoCapitalize="none" autoCorrect={false} className="mb-4" />
      <Input label="Сумма (µT)" placeholder="например 100000" value={amount}
        onChangeText={setAmount} keyboardType="numeric" className="mb-4" />
      <Input label="Комиссия (µT)" value={fee}
        onChangeText={setFee} keyboardType="numeric" className="mb-8" />

      <TouchableOpacity
        onPress={onSend}
        disabled={sending}
        style={{
          paddingVertical: 15, borderRadius: 10, alignItems: 'center', flexDirection: 'row',
          justifyContent: 'center', gap: 8,
          backgroundColor: sending ? C.surface2 : C.accent,
        }}
      >
        {!sending && <Ionicons name="paper-plane-outline" size={18} color="#0b1220" />}
        <Text style={{ color: sending ? C.muted : '#0b1220', fontWeight: '700', fontSize: 15 }}>
          {sending ? 'Отправка…' : 'Подтвердить'}
        </Text>
      </TouchableOpacity>
    </View>
  );
}

// ─── TX Detail Sheet ──────────────────────────────────────────────────────────

function TxDetailSheet({
  tx, myPubKey, onClose,
}: {
  tx: TxRecord; myPubKey: string; onClose: () => void;
}) {
  const [copiedHash, setCopiedHash] = useState(false);
  const meta     = txMeta(tx.type);
  const isSent   = tx.from === myPubKey;
  const amtValue = tx.amount ?? 0;

  const copyHash = async () => {
    await Clipboard.setStringAsync(tx.hash);
    setCopiedHash(true);
    setTimeout(() => setCopiedHash(false), 2000);
  };

  const amtColor = amtValue === 0 ? C.muted : isSent ? C.err : C.ok;
  const amtSign  = amtValue === 0 ? '' : isSent ? '−' : '+';

  return (
    <View style={{ flex: 1, backgroundColor: C.bg }}>
      {/* Handle */}
      <View style={{ alignItems: 'center', paddingTop: 12, marginBottom: 4 }}>
        <View style={{ width: 36, height: 4, borderRadius: 2, backgroundColor: C.line }} />
      </View>

      <ScrollView contentContainerStyle={{ paddingHorizontal: 16, paddingTop: 8, paddingBottom: 32 }}>
        {/* Header */}
        <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
          <Text style={{ color: C.text, fontSize: 17, fontWeight: '700' }}>Транзакция</Text>
          <TouchableOpacity onPress={onClose} style={{ padding: 8, backgroundColor: C.surface2, borderRadius: 8 }}>
            <Ionicons name="close-outline" size={18} color={C.muted} />
          </TouchableOpacity>
        </View>

        {/* Hero */}
        <View style={{ backgroundColor: C.surface, borderRadius: 12, padding: 20, alignItems: 'center', marginBottom: 16 }}>
          <View style={{
            width: 56, height: 56, borderRadius: 28,
            backgroundColor: `${meta.color}18`,
            alignItems: 'center', justifyContent: 'center', marginBottom: 12,
          }}>
            <Ionicons name={meta.icon} size={26} color={meta.color} />
          </View>
          <Text style={{ color: C.text, fontSize: 16, fontWeight: '600', marginBottom: amtValue > 0 ? 8 : 0 }}>
            {meta.label}
          </Text>
          {amtValue > 0 && (
            <Text style={{ color: amtColor, fontSize: 30, fontWeight: '700', letterSpacing: -0.5 }}>
              {amtSign}{formatAmount(amtValue)}
            </Text>
          )}
          <View style={{
            marginTop: 12, paddingHorizontal: 12, paddingVertical: 4,
            borderRadius: 999,
            backgroundColor: tx.status === 'confirmed' ? 'rgba(65,201,138,0.12)' : 'rgba(240,179,90,0.12)',
          }}>
            <Text style={{ color: tx.status === 'confirmed' ? C.ok : C.warn, fontSize: 12, fontWeight: '600' }}>
              {tx.status === 'confirmed' ? '✓ Подтверждена' : '⏳ В обработке'}
            </Text>
          </View>
        </View>

        {/* Details table */}
        <View style={{ backgroundColor: C.surface, borderRadius: 12, overflow: 'hidden', marginBottom: 16 }}>
          <DetailRow icon="code-outline"        label="Тип"      value={tx.type} mono first />
          {tx.amount !== undefined && (
            <DetailRow icon="cash-outline"      label="Сумма"    value={`${tx.amount.toLocaleString()} µT`} />
          )}
          <DetailRow icon="pricetag-outline"    label="Комиссия" value={`${(tx.fee ?? 0).toLocaleString()} µT`} />
          {tx.timestamp > 0 && (
            <DetailRow icon="time-outline"      label="Время"    value={new Date(tx.timestamp * 1000).toLocaleString()} />
          )}
        </View>

        {/* Addresses */}
        <View style={{ backgroundColor: C.surface, borderRadius: 12, overflow: 'hidden', marginBottom: 16 }}>
          {/* "From" for synthetic txs (empty tx.from) reads "Сеть" rather than an empty row. */}
          <DetailRow
            icon="person-outline"
            label="От"
            value={tx.from || 'Сеть (синтетическая tx)'}
            mono={!!tx.from}
            truncate={!!tx.from}
            first
          />
          {tx.to && (
            <DetailRow icon="arrow-forward-outline" label="Кому" value={tx.to} mono truncate />
          )}
        </View>

        {/* TX Hash */}
        <View style={{ backgroundColor: C.surface, borderRadius: 12, overflow: 'hidden', marginBottom: 20 }}>
          <View style={{ paddingHorizontal: 14, paddingVertical: 12 }}>
            <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, marginBottom: 6 }}>
              <Ionicons name="receipt-outline" size={13} color={C.muted} />
              <Text style={{ color: C.muted, fontSize: 11, letterSpacing: 0.5, textTransform: 'uppercase' }}>
                TX ID / Hash
              </Text>
            </View>
            <Text style={{ color: C.text, fontFamily: 'monospace', fontSize: 11, lineHeight: 17 }}>
              {tx.hash}
            </Text>
          </View>
        </View>

        <TouchableOpacity
          onPress={copyHash}
          style={{
            paddingVertical: 13, borderRadius: 10, alignItems: 'center',
            flexDirection: 'row', justifyContent: 'center', gap: 8,
            backgroundColor: copiedHash ? 'rgba(65,201,138,0.12)' : C.surface2,
          }}
        >
          <Ionicons
            name={copiedHash ? 'checkmark-outline' : 'copy-outline'}
            size={16}
            color={copiedHash ? C.ok : C.text}
          />
          <Text style={{ color: copiedHash ? C.ok : C.text, fontWeight: '600', fontSize: 14 }}>
            {copiedHash ? 'Скопировано' : 'Копировать хеш'}
          </Text>
        </TouchableOpacity>
      </ScrollView>
    </View>
  );
}

// ─── Detail Row ───────────────────────────────────────────────────────────────

function DetailRow({
  icon, label, value, mono, truncate, first,
}: {
  icon: keyof typeof Ionicons.glyphMap;
  label: string; value: string;
  mono?: boolean; truncate?: boolean; first?: boolean;
}) {
  return (
    <View style={{
      flexDirection: 'row', alignItems: 'center',
      paddingHorizontal: 14, paddingVertical: 11,
      borderTopWidth: first ? 0 : 1, borderTopColor: C.line,
      gap: 10,
    }}>
      <Ionicons name={icon} size={14} color={C.muted} style={{ width: 16 }} />
      <Text style={{ color: C.muted, fontSize: 13, width: 72 }}>{label}</Text>
      <Text
        style={{
          color: C.text,
          flex: 1,
          textAlign: 'right',
          fontFamily: mono ? 'monospace' : undefined,
          fontSize: mono ? 11 : 13,
        }}
        numberOfLines={truncate ? 1 : undefined}
        ellipsizeMode="middle"
      >
        {value}
      </Text>
    </View>
  );
}
