/**
 * Wallet screen — dark minimalist.
 *
 * Сетка:
 *   [TabHeader: profile-avatar | Wallet | refresh]
 *   [Balance hero card — gradient-ish dark card, big number, address chip, action row]
 *   [SectionLabel: Recent transactions]
 *   [TX list card — tiles per tx, in/out coloring, relative time]
 *   [Send modal: slide-up sheet с полями recipient/amount/fee + total preview]
 *
 * Все кнопки и инпуты — те же плоские стили, что на других экранах.
 * Никаких style-функций у Pressable'ов с layout-пропсами (избегаем web
 * layout-баги, которые мы уже ловили на ChatTile/MessageBubble).
 */
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import {
  View, Text, ScrollView, Modal, Alert, RefreshControl, Pressable, TextInput, ActivityIndicator,
} 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, humanizeTxError } from '@/lib/api';
import { shortAddr } from '@/lib/crypto';
import { formatAmount, relativeTime } from '@/lib/utils';
import type { TxRecord } from '@/lib/types';

import { TabHeader } from '@/components/TabHeader';
import { IconButton } from '@/components/IconButton';

// ─── TX meta (icon + label + tone) ─────────────────────────────────

type IoniconName = React.ComponentProps<typeof Ionicons>['name'];

interface TxMeta {
  label: string;
  icon:  IoniconName;
  tone:  'in' | 'out' | 'neutral';
}

const TX_META: Record<string, TxMeta> = {
  TRANSFER:        { label: 'Transfer',         icon: 'swap-horizontal-outline', tone: 'neutral' },
  CONTACT_REQUEST: { label: 'Contact request',  icon: 'person-add-outline',      tone: 'out' },
  ACCEPT_CONTACT:  { label: 'Contact accepted', icon: 'person-outline',          tone: 'in'  },
  BLOCK_CONTACT:   { label: 'Block',            icon: 'ban-outline',             tone: 'out' },
  DEPLOY_CONTRACT: { label: 'Deploy',           icon: 'document-text-outline',   tone: 'out' },
  CALL_CONTRACT:   { label: 'Call contract',    icon: 'flash-outline',           tone: 'out' },
  STAKE:           { label: 'Stake',            icon: 'lock-closed-outline',     tone: 'out' },
  UNSTAKE:         { label: 'Unstake',          icon: 'lock-open-outline',       tone: 'in'  },
  REGISTER_KEY:    { label: 'Register key',     icon: 'key-outline',             tone: 'neutral' },
  BLOCK_REWARD:    { label: 'Block reward',     icon: 'diamond-outline',         tone: 'in'  },
};

function txMeta(type: string): TxMeta {
  return TX_META[type] ?? { label: type.replace(/_/g, ' '), icon: 'ellipse-outline', tone: 'neutral' };
}

const toneColor = (tone: TxMeta['tone']): string =>
  tone === 'in' ? '#3ba55d' : tone === 'out' ? '#f4212e' : '#e7e7e7';

// ─── Main ──────────────────────────────────────────────────────────

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

  useBalance();

  const [txHistory,  setTxHistory]  = useState<TxRecord[]>([]);
  const [refreshing, setRefreshing] = useState(false);
  const [copied,     setCopied]     = useState(false);
  const [showSend,   setShowSend]   = 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 { /* ignore — WS/HTTP retries sample */ }
    setRefreshing(false);
  }, [keyFile, setBalance]);

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

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

  const mine = keyFile?.pub_key ?? '';

  return (
    <View style={{ flex: 1, backgroundColor: '#000000', paddingTop: insets.top }}>
      <TabHeader
        title="Wallet"
        right={<IconButton icon="refresh-outline" size={36} onPress={load} />}
      />

      <ScrollView
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={load} tintColor="#1d9bf0" />}
        contentContainerStyle={{ paddingBottom: 120 }}
        showsVerticalScrollIndicator={false}
      >
        <BalanceHero
          balance={balance}
          address={mine}
          copied={copied}
          onCopy={copyAddress}
          onSend={() => setShowSend(true)}
        />

        <SectionLabel>Recent transactions</SectionLabel>

        {txHistory.length === 0 ? (
          <EmptyTx />
        ) : (
          <View
            style={{
              marginHorizontal: 14,
              borderRadius: 14,
              backgroundColor: '#0a0a0a',
              borderWidth: 1, borderColor: '#1f1f1f',
              overflow: 'hidden',
            }}
          >
            {txHistory.map((tx, i) => (
              <TxTile
                key={tx.hash + i}
                tx={tx}
                first={i === 0}
                mine={mine}
              />
            ))}
          </View>
        )}
      </ScrollView>

      <SendModal
        visible={showSend}
        onClose={() => setShowSend(false)}
        balance={balance}
        keyFile={keyFile}
        onSent={() => {
          setShowSend(false);
          setTimeout(load, 1200);
        }}
      />
    </View>
  );
}

// ─── Hero card ─────────────────────────────────────────────────────

function BalanceHero({
  balance, address, copied, onCopy, onSend,
}: {
  balance: number;
  address: string;
  copied: boolean;
  onCopy: () => void;
  onSend: () => void;
}) {
  return (
    <View
      style={{
        marginHorizontal: 14,
        marginTop: 10,
        padding: 20,
        borderRadius: 18,
        backgroundColor: '#0a0a0a',
        borderWidth: 1,
        borderColor: '#1f1f1f',
      }}
    >
      <Text style={{ color: '#8b8b8b', fontSize: 12, letterSpacing: 0.3 }}>
        Balance
      </Text>
      <Text
        style={{
          color: '#ffffff',
          fontSize: 36,
          fontWeight: '800',
          letterSpacing: -0.8,
          marginTop: 4,
        }}
      >
        {formatAmount(balance)}
      </Text>

      {/* Address chip */}
      <Pressable onPress={onCopy} style={{ marginTop: 14 }}>
        <View
          style={{
            flexDirection: 'row',
            alignItems: 'center',
            backgroundColor: '#111111',
            borderRadius: 10,
            paddingHorizontal: 12,
            paddingVertical: 9,
          }}
        >
          <Ionicons
            name={copied ? 'checkmark-outline' : 'copy-outline'}
            size={14}
            color={copied ? '#3ba55d' : '#8b8b8b'}
          />
          <Text
            style={{
              color: copied ? '#3ba55d' : '#8b8b8b',
              fontSize: 12,
              marginLeft: 6,
              fontFamily: 'monospace',
              flex: 1,
            }}
            numberOfLines={1}
          >
            {copied ? 'Copied!' : shortAddr(address, 10)}
          </Text>
        </View>
      </Pressable>

      {/* Actions */}
      <View style={{ flexDirection: 'row', gap: 10, marginTop: 14 }}>
        <HeroButton icon="paper-plane-outline" label="Send" primary onPress={onSend} />
        <HeroButton icon="download-outline" label="Receive" onPress={onCopy} />
      </View>
    </View>
  );
}

function HeroButton({
  icon, label, primary, onPress,
}: {
  icon: IoniconName;
  label: string;
  primary?: boolean;
  onPress: () => void;
}) {
  const base = {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 11,
    borderRadius: 999,
    gap: 6,
  } as const;
  return (
    <Pressable onPress={onPress} style={{ flex: 1 }}>
      {({ pressed }) => (
        <View
          style={{
            ...base,
            backgroundColor: primary
              ? (pressed ? '#1a8cd8' : '#1d9bf0')
              : (pressed ? '#202020' : '#111111'),
            borderWidth: primary ? 0 : 1,
            borderColor: '#1f1f1f',
          }}
        >
          <Ionicons name={icon} size={15} color="#ffffff" />
          <Text style={{ color: '#ffffff', fontWeight: '700', fontSize: 14 }}>
            {label}
          </Text>
        </View>
      )}
    </Pressable>
  );
}

// ─── Section label ────────────────────────────────────────────────

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

// ─── Empty state ──────────────────────────────────────────────────

function EmptyTx() {
  return (
    <View
      style={{
        marginHorizontal: 14,
        borderRadius: 14,
        backgroundColor: '#0a0a0a',
        borderWidth: 1,
        borderColor: '#1f1f1f',
        paddingVertical: 36,
        alignItems: 'center',
      }}
    >
      <Ionicons name="receipt-outline" size={32} color="#5a5a5a" />
      <Text style={{ color: '#8b8b8b', fontSize: 13, marginTop: 8 }}>
        No transactions yet
      </Text>
      <Text style={{ color: '#5a5a5a', fontSize: 11, marginTop: 2 }}>
        Pull to refresh
      </Text>
    </View>
  );
}

// ─── TX tile ──────────────────────────────────────────────────────
//
// Pressable с ВНЕШНИМ плоским style (background через static object),
// внутренняя View handles row-layout. Избегаем web-баг со style-функциями
// Pressable'а.

function TxTile({
  tx, first, mine,
}: {
  tx: TxRecord;
  first: boolean;
  mine: string;
}) {
  const m = txMeta(tx.type);
  const isMineTx = tx.from === mine;
  const amt = tx.amount ?? 0;
  const sign  = m.tone === 'in' ? '+' : m.tone === 'out' ? '−' : '';
  const color = toneColor(m.tone);

  return (
    <Pressable>
      <View
        style={{
          flexDirection: 'row',
          alignItems: 'center',
          paddingHorizontal: 14,
          paddingVertical: 12,
          borderTopWidth: first ? 0 : 1,
          borderTopColor: '#1f1f1f',
        }}
      >
        <View
          style={{
            width: 36,
            height: 36,
            borderRadius: 10,
            backgroundColor: '#111111',
            alignItems: 'center',
            justifyContent: 'center',
            marginRight: 12,
          }}
        >
          <Ionicons name={m.icon} size={16} color="#e7e7e7" />
        </View>
        <View style={{ flex: 1, minWidth: 0 }}>
          <Text style={{ color: '#ffffff', fontSize: 14, fontWeight: '600' }}>
            {m.label}
          </Text>
          <Text
            style={{
              color: '#8b8b8b',
              fontSize: 11,
              marginTop: 1,
              fontFamily: 'monospace',
            }}
            numberOfLines={1}
          >
            {tx.type === 'TRANSFER'
              ? (isMineTx ? `→ ${shortAddr(tx.to ?? '', 5)}` : `← ${shortAddr(tx.from, 5)}`)
              : shortAddr(tx.hash, 8)}
            {'  ·  '}
            {relativeTime(tx.timestamp)}
          </Text>
        </View>
        {amt > 0 && (
          <Text style={{ color, fontWeight: '700', fontSize: 14 }}>
            {sign}{formatAmount(amt)}
          </Text>
        )}
      </View>
    </Pressable>
  );
}

// ─── Send modal ───────────────────────────────────────────────────

function SendModal({
  visible, onClose, balance, keyFile, onSent,
}: {
  visible: boolean;
  onClose: () => void;
  balance: number;
  keyFile: { pub_key: string; priv_key: string } | null;
  onSent: () => void;
}) {
  const insets = useSafeAreaInsets();
  const [to,     setTo]     = useState('');
  const [amount, setAmount] = useState('');
  const [fee,    setFee]    = useState('1000');
  const [sending, setSending] = useState(false);

  useEffect(() => {
    if (!visible) {
      // reset при закрытии
      setTo(''); setAmount(''); setFee('1000'); setSending(false);
    }
  }, [visible]);

  const amt = parseInt(amount || '0', 10) || 0;
  const f   = parseInt(fee    || '0', 10) || 0;
  const total = amt + f;
  const ok = !!to.trim() && amt > 0 && total <= balance;

  const send = async () => {
    if (!keyFile) return;
    if (!ok) {
      Alert.alert('Check inputs', total > balance
        ? `Need ${formatAmount(total)}, have ${formatAmount(balance)}.`
        : 'Recipient and amount are required.');
      return;
    }
    setSending(true);
    try {
      const tx = buildTransferTx({
        from: keyFile.pub_key,
        to: to.trim(),
        amount: amt,
        fee: f,
        privKey: keyFile.priv_key,
      });
      await submitTx(tx);
      onSent();
    } catch (e: any) {
      Alert.alert('Send failed', humanizeTxError(e));
    } finally {
      setSending(false);
    }
  };

  return (
    <Modal visible={visible} animationType="slide" transparent onRequestClose={onClose}>
      <Pressable
        onPress={onClose}
        style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.82)', justifyContent: 'flex-end' }}
      >
        <Pressable
          onPress={() => { /* block bubble-close */ }}
          style={{
            backgroundColor: '#0a0a0a',
            borderTopLeftRadius: 20,
            borderTopRightRadius: 20,
            paddingTop: 10,
            paddingBottom: Math.max(insets.bottom, 14) + 12,
            paddingHorizontal: 14,
            borderTopWidth: 1,
            borderColor: '#1f1f1f',
          }}
        >
          <View
            style={{
              alignSelf: 'center',
              width: 40, height: 4, borderRadius: 2,
              backgroundColor: '#2a2a2a',
              marginBottom: 14,
            }}
          />
          <Text style={{ color: '#ffffff', fontSize: 18, fontWeight: '700', marginBottom: 14 }}>
            Send tokens
          </Text>

          <Field label="Recipient address">
            <TextInput
              value={to}
              onChangeText={setTo}
              placeholder="DC… or pub_key hex"
              placeholderTextColor="#5a5a5a"
              autoCapitalize="none"
              autoCorrect={false}
              style={{
                color: '#ffffff',
                fontSize: 13,
                fontFamily: 'monospace',
                paddingVertical: 0,
              }}
            />
          </Field>

          <View style={{ flexDirection: 'row', gap: 10, marginTop: 10 }}>
            <View style={{ flex: 2 }}>
              <Field label="Amount (µT)">
                <TextInput
                  value={amount}
                  onChangeText={setAmount}
                  placeholder="1000"
                  placeholderTextColor="#5a5a5a"
                  keyboardType="numeric"
                  style={{ color: '#ffffff', fontSize: 14, paddingVertical: 0 }}
                />
              </Field>
            </View>
            <View style={{ flex: 1 }}>
              <Field label="Fee (µT)">
                <TextInput
                  value={fee}
                  onChangeText={setFee}
                  placeholder="1000"
                  placeholderTextColor="#5a5a5a"
                  keyboardType="numeric"
                  style={{ color: '#ffffff', fontSize: 14, paddingVertical: 0 }}
                />
              </Field>
            </View>
          </View>

          {/* Summary */}
          <View
            style={{
              marginTop: 12,
              padding: 12,
              borderRadius: 10,
              backgroundColor: '#111111',
              borderWidth: 1,
              borderColor: '#1f1f1f',
            }}
          >
            <SummaryRow label="Amount" value={formatAmount(amt)} />
            <SummaryRow label="Fee"    value={formatAmount(f)} muted />
            <View style={{ height: 1, backgroundColor: '#1f1f1f', marginVertical: 6 }} />
            <SummaryRow
              label="Total"
              value={formatAmount(total)}
              accent={total > balance ? '#f4212e' : '#ffffff'}
            />
          </View>

          <View style={{ flexDirection: 'row', gap: 10, marginTop: 16 }}>
            <Pressable onPress={onClose} style={{ flex: 1 }}>
              {({ pressed }) => (
                <View
                  style={{
                    alignItems: 'center',
                    justifyContent: 'center',
                    paddingVertical: 12,
                    borderRadius: 999,
                    backgroundColor: pressed ? '#1a1a1a' : '#111111',
                    borderWidth: 1,
                    borderColor: '#1f1f1f',
                  }}
                >
                  <Text style={{ color: '#ffffff', fontWeight: '600', fontSize: 14 }}>
                    Cancel
                  </Text>
                </View>
              )}
            </Pressable>
            <Pressable onPress={send} disabled={!ok || sending} style={{ flex: 2 }}>
              {({ pressed }) => (
                <View
                  style={{
                    alignItems: 'center',
                    justifyContent: 'center',
                    paddingVertical: 12,
                    borderRadius: 999,
                    backgroundColor: !ok || sending
                      ? '#1a1a1a'
                      : pressed ? '#1a8cd8' : '#1d9bf0',
                  }}
                >
                  {sending ? (
                    <ActivityIndicator color="#ffffff" size="small" />
                  ) : (
                    <Text style={{ color: '#ffffff', fontWeight: '700', fontSize: 14 }}>
                      Send
                    </Text>
                  )}
                </View>
              )}
            </Pressable>
          </View>
        </Pressable>
      </Pressable>
    </Modal>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <View>
      <Text style={{ color: '#8b8b8b', fontSize: 12, marginBottom: 6 }}>{label}</Text>
      <View
        style={{
          backgroundColor: '#000000',
          borderRadius: 10,
          paddingHorizontal: 12,
          paddingVertical: 10,
          borderWidth: 1,
          borderColor: '#1f1f1f',
        }}
      >
        {children}
      </View>
    </View>
  );
}

function SummaryRow({
  label, value, muted, accent,
}: {
  label: string;
  value: string;
  muted?: boolean;
  accent?: string;
}) {
  return (
    <View
      style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        paddingVertical: 3,
      }}
    >
      <Text style={{ color: '#8b8b8b', fontSize: 12 }}>{label}</Text>
      <Text
        style={{
          color: accent ?? (muted ? '#8b8b8b' : '#ffffff'),
          fontSize: 13,
          fontWeight: muted ? '500' : '700',
        }}
      >
        {value}
      </Text>
    </View>
  );
}
