/**
 * Transaction detail screen — shows everything the block explorer
 * does for a single tx, so the user can audit any action they took
 * (transfer, post, like, contact request) without leaving the app.
 *
 * Route: /(app)/tx/[id]
 *
 * Triggered from: wallet history (TxTile tap). Will also be reachable
 * from post detail / profile timestamp once we wire those up (Phase
 * v2.1 idea).
 *
 * Layout matches the style of the profile info card:
 *   [back] Transaction
 *
 *   [ICON]  <TYPE>
 *           <relative time> · <status>
 *
 *   [amount pill, big, signed ± + tone colour]  (for TRANSFER-ish)
 *
 *   Info card rows:
 *     ID            <hash>                 (tap → copy)
 *     From          <addr>                 (tap → copy)
 *     To            <addr>                 (tap → copy)
 *     Block         #N
 *     Time          <human>
 *     Fee           0.001 T
 *     Gas           1234 (if CALL_CONTRACT)
 *     Memo          (if set)
 *
 *   [payload section, collapsible — raw JSON or hex]
 */
import React, { useCallback, useEffect, useState } from 'react';
import {
  View, Text, ScrollView, ActivityIndicator, Pressable,
} from 'react-native';
import * as Clipboard from 'expo-clipboard';
import { Ionicons } from '@expo/vector-icons';
import { useLocalSearchParams } from 'expo-router';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { Header } from '@/components/Header';
import { IconButton } from '@/components/IconButton';
import { getTxDetail, type TxDetail } from '@/lib/api';
import { useStore } from '@/lib/store';
import { safeBack, formatAmount } from '@/lib/utils';

function shortAddr(a: string, n = 8): string {
  if (!a) return '—';
  return a.length <= n * 2 + 1 ? a : `${a.slice(0, n)}…${a.slice(-n)}`;
}

// Copy of the tx-type metadata used by wallet.tsx — keeps the icon +
// label consistent whichever screen surfaces the tx.
function txMeta(type: string): {
  icon: React.ComponentProps<typeof Ionicons>['name'];
  label: string;
  tone: 'in' | 'out' | 'neutral';
} {
  switch (type) {
    case 'TRANSFER':         return { icon: 'swap-horizontal',  label: 'Transfer',          tone: 'neutral' };
    case 'CONTACT_REQUEST':  return { icon: 'person-add',       label: 'Contact request',   tone: 'out' };
    case 'ACCEPT_CONTACT':   return { icon: 'checkmark-circle', label: 'Accepted contact',  tone: 'neutral' };
    case 'BLOCK_CONTACT':    return { icon: 'ban',              label: 'Blocked contact',   tone: 'neutral' };
    case 'REGISTER_KEY':     return { icon: 'key',              label: 'Identity registered', tone: 'neutral' };
    case 'REGISTER_RELAY':   return { icon: 'globe',            label: 'Relay registered',  tone: 'neutral' };
    case 'BIND_WALLET':      return { icon: 'wallet',           label: 'Wallet bound',      tone: 'neutral' };
    case 'RELAY_PROOF':      return { icon: 'receipt',          label: 'Relay proof',       tone: 'in'  };
    case 'BLOCK_REWARD':     return { icon: 'trophy',           label: 'Block reward',      tone: 'in'  };
    case 'HEARTBEAT':        return { icon: 'pulse',            label: 'Heartbeat',         tone: 'neutral' };
    case 'CREATE_POST':      return { icon: 'newspaper',        label: 'Post published',    tone: 'out' };
    case 'DELETE_POST':      return { icon: 'trash',            label: 'Post deleted',      tone: 'neutral' };
    case 'LIKE_POST':        return { icon: 'heart',            label: 'Like',              tone: 'neutral' };
    case 'UNLIKE_POST':      return { icon: 'heart-dislike',    label: 'Unlike',            tone: 'neutral' };
    case 'FOLLOW':           return { icon: 'person-add',       label: 'Follow',            tone: 'neutral' };
    case 'UNFOLLOW':         return { icon: 'person-remove',    label: 'Unfollow',          tone: 'neutral' };
    case 'CALL_CONTRACT':    return { icon: 'terminal',         label: 'Contract call',     tone: 'neutral' };
    case 'DEPLOY_CONTRACT':  return { icon: 'cube',             label: 'Contract deployed', tone: 'neutral' };
    case 'STAKE':            return { icon: 'lock-closed',      label: 'Stake',             tone: 'out' };
    case 'UNSTAKE':          return { icon: 'lock-open',        label: 'Unstake',           tone: 'in'  };
    default:                 return { icon: 'document',         label: type || 'Transaction', tone: 'neutral' };
  }
}

function toneColor(tone: 'in' | 'out' | 'neutral'): string {
  if (tone === 'in')  return '#3ba55d';
  if (tone === 'out') return '#f4212e';
  return '#ffffff';
}

export default function TxDetailScreen() {
  const insets  = useSafeAreaInsets();
  const { id }  = useLocalSearchParams<{ id: string }>();
  const keyFile = useStore(s => s.keyFile);

  const [tx, setTx]           = useState<TxDetail | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError]     = useState<string | null>(null);
  const [copied, setCopied]   = useState<string | null>(null);
  const [payloadOpen, setPayloadOpen] = useState(false);

  useEffect(() => {
    if (!id) return;
    let cancelled = false;
    setLoading(true);
    setError(null);
    getTxDetail(id)
      .then(res => { if (!cancelled) setTx(res); })
      .catch(e => { if (!cancelled) setError(String(e?.message ?? e)); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [id]);

  const copy = useCallback(async (field: string, value: string) => {
    await Clipboard.setStringAsync(value);
    setCopied(field);
    setTimeout(() => setCopied(f => (f === field ? null : f)), 1500);
  }, []);

  const meta = tx ? txMeta(tx.type) : null;
  const mine = keyFile?.pub_key ?? '';
  const isMineOut = tx ? tx.from === mine && tx.to !== mine : false;
  const isMineIn  = tx ? tx.to === mine && tx.from !== mine : false;
  const showAmount = tx ? tx.amount_ut > 0 : false;
  // Sign based on perspective: money leaving my wallet → minus, coming in → plus.
  const sign = isMineOut ? '−' : isMineIn ? '+' : '';
  const amountColor =
    isMineOut ? '#f4212e'
    : isMineIn ? '#3ba55d'
    : '#ffffff';

  return (
    <View style={{ flex: 1, backgroundColor: '#000000', paddingTop: insets.top }}>
      <Header
        title="Transaction"
        divider
        left={<IconButton icon="chevron-back" size={36} onPress={() => safeBack()} />}
      />

      {loading ? (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <ActivityIndicator color="#1d9bf0" />
        </View>
      ) : error ? (
        <View style={{ padding: 24 }}>
          <Text style={{ color: '#f4212e', fontSize: 14 }}>{error}</Text>
        </View>
      ) : !tx ? (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 32 }}>
          <Ionicons name="help-circle-outline" size={40} color="#3a3a3a" />
          <Text style={{ color: '#ffffff', fontSize: 16, fontWeight: '700', marginTop: 10 }}>
            Not found
          </Text>
          <Text style={{ color: '#8b8b8b', fontSize: 13, textAlign: 'center', marginTop: 6 }}>
            No transaction with this ID on this chain.
          </Text>
        </View>
      ) : (
        <ScrollView contentContainerStyle={{ padding: 14, paddingBottom: 40 }}>
          {/* ── Hero row: icon + type + time ───────────────────────── */}
          <View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 16 }}>
            <View
              style={{
                width: 48, height: 48, borderRadius: 14,
                backgroundColor: '#111111',
                borderWidth: 1, borderColor: '#1f1f1f',
                alignItems: 'center', justifyContent: 'center',
                marginRight: 12,
              }}
            >
              <Ionicons name={meta!.icon} size={22} color="#ffffff" />
            </View>
            <View style={{ flex: 1, minWidth: 0 }}>
              <Text style={{ color: '#ffffff', fontSize: 17, fontWeight: '700' }}>
                {meta!.label}
              </Text>
              <Text style={{ color: '#8b8b8b', fontSize: 12, marginTop: 2 }}>
                {new Date(tx.time).toLocaleString()}
              </Text>
            </View>
          </View>

          {/* ── Amount big number — only for txs that move tokens ── */}
          {showAmount && (
            <View
              style={{
                alignItems: 'center',
                paddingVertical: 18,
                borderRadius: 14,
                backgroundColor: '#0a0a0a',
                borderWidth: 1, borderColor: '#1f1f1f',
                marginBottom: 14,
              }}
            >
              <Text style={{
                color: amountColor,
                fontSize: 32,
                fontWeight: '800',
                letterSpacing: -0.8,
              }}>
                {sign}{formatAmount(tx.amount_ut)}
              </Text>
              <Text style={{ color: '#6a6a6a', fontSize: 11, marginTop: 2 }}>
                {tx.amount}
              </Text>
            </View>
          )}

          {/* ── Info card ───────────────────────────────────────────── */}
          <View
            style={{
              borderRadius: 14,
              backgroundColor: '#0a0a0a',
              borderWidth: 1, borderColor: '#1f1f1f',
              overflow: 'hidden',
            }}
          >
            <CopyRow
              label="Tx ID"
              value={shortAddr(tx.id, 8)}
              rawValue={tx.id}
              field="id"
              copied={copied}
              onCopy={copy}
              mono
            />
            <Divider />
            <CopyRow
              label="From"
              value={shortAddr(tx.from, 8)}
              rawValue={tx.from}
              field="from"
              copied={copied}
              onCopy={copy}
              mono
              highlight={tx.from === mine ? 'you' : undefined}
            />
            {tx.to && (
              <>
                <Divider />
                <CopyRow
                  label="To"
                  value={shortAddr(tx.to, 8)}
                  rawValue={tx.to}
                  field="to"
                  copied={copied}
                  onCopy={copy}
                  mono
                  highlight={tx.to === mine ? 'you' : undefined}
                />
              </>
            )}
            <Divider />
            <InfoRow label="Block" value={`#${tx.block_index}`} />
            <Divider />
            <InfoRow label="Fee" value={formatAmount(tx.fee_ut)} />
            {tx.gas_used ? (
              <>
                <Divider />
                <InfoRow label="Gas used" value={String(tx.gas_used)} />
              </>
            ) : null}
            {tx.memo ? (
              <>
                <Divider />
                <InfoRow label="Memo" value={tx.memo} />
              </>
            ) : null}
          </View>

          {/* ── Payload expand ─────────────────────────────────────── */}
          {(tx.payload || tx.payload_hex) && (
            <View style={{ marginTop: 14 }}>
              <Pressable
                onPress={() => setPayloadOpen(o => !o)}
                style={({ pressed }) => ({
                  flexDirection: 'row',
                  alignItems: 'center',
                  paddingVertical: 10,
                  paddingHorizontal: 14,
                  backgroundColor: pressed ? '#0f0f0f' : '#0a0a0a',
                  borderWidth: 1, borderColor: '#1f1f1f',
                  borderRadius: 14,
                })}
              >
                <Ionicons name="code-slash" size={14} color="#8b8b8b" />
                <Text style={{ color: '#ffffff', fontSize: 13, fontWeight: '600', marginLeft: 8, flex: 1 }}>
                  Payload
                </Text>
                <Ionicons
                  name={payloadOpen ? 'chevron-up' : 'chevron-down'}
                  size={14}
                  color="#6a6a6a"
                />
              </Pressable>
              {payloadOpen && (
                <View
                  style={{
                    marginTop: 8,
                    padding: 12,
                    borderRadius: 12,
                    backgroundColor: '#050505',
                    borderWidth: 1, borderColor: '#1f1f1f',
                  }}
                >
                  <Text
                    selectable
                    style={{
                      color: '#d0d0d0',
                      fontSize: 11,
                      fontFamily: 'monospace',
                      lineHeight: 16,
                    }}
                  >
                    {tx.payload
                      ? JSON.stringify(tx.payload, null, 2)
                      : `hex: ${tx.payload_hex}`}
                  </Text>
                </View>
              )}
            </View>
          )}

          {/* Signature as a final copyable row, small */}
          {tx.signature_hex && (
            <View
              style={{
                marginTop: 14,
                borderRadius: 14,
                backgroundColor: '#0a0a0a',
                borderWidth: 1, borderColor: '#1f1f1f',
                overflow: 'hidden',
              }}
            >
              <CopyRow
                label="Signature"
                value={shortAddr(tx.signature_hex, 10)}
                rawValue={tx.signature_hex}
                field="signature"
                copied={copied}
                onCopy={copy}
                mono
              />
            </View>
          )}
        </ScrollView>
      )}
    </View>
  );
}

// ── Rows ──────────────────────────────────────────────────────────────

function Divider() {
  return <View style={{ height: 1, backgroundColor: '#1f1f1f' }} />;
}

function InfoRow({ label, value }: { label: string; value: string }) {
  return (
    <View
      style={{
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 14,
        paddingVertical: 12,
      }}
    >
      <Text style={{ color: '#8b8b8b', fontSize: 13, flex: 1 }}>{label}</Text>
      <Text style={{ color: '#ffffff', fontSize: 13, fontWeight: '600' }} numberOfLines={1}>
        {value}
      </Text>
    </View>
  );
}

function CopyRow({
  label, value, rawValue, field, copied, onCopy, mono, highlight,
}: {
  label: string;
  value: string;
  rawValue: string;
  field: string;
  copied: string | null;
  onCopy: (field: string, value: string) => void;
  mono?: boolean;
  highlight?: 'you';
}) {
  const isCopied = copied === field;
  return (
    <Pressable
      onPress={() => onCopy(field, rawValue)}
      style={({ pressed }) => ({
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 14,
        paddingVertical: 12,
        backgroundColor: pressed ? '#0f0f0f' : 'transparent',
      })}
    >
      <Text style={{ color: '#8b8b8b', fontSize: 13, flex: 1 }}>{label}</Text>
      <Text
        style={{
          color: isCopied
            ? '#3ba55d'
            : highlight === 'you'
              ? '#1d9bf0'
              : '#ffffff',
          fontSize: 13,
          fontFamily: mono ? 'monospace' : undefined,
          fontWeight: '600',
          marginRight: 8,
        }}
        numberOfLines={1}
      >
        {isCopied
          ? 'Copied'
          : highlight === 'you'
            ? `${value} (you)`
            : value}
      </Text>
      <Ionicons
        name={isCopied ? 'checkmark' : 'copy-outline'}
        size={13}
        color={isCopied ? '#3ba55d' : '#6a6a6a'}
      />
    </Pressable>
  );
}
