/**
 * Mempool page showing pending (unconfirmed) transactions.
 * Features real-time WebSocket updates as new transactions enter the mempool.
 */

import { useState, useEffect, useMemo } from 'react';
import { Link } from 'react-router-dom';
import {
  Clock,
  Coins,
  Radio,
  ArrowRight,
  Layers,
  Zap,
  TrendingUp,
} from 'lucide-react';
import { useMempool } from '../hooks/useApi';
import { useRealtimeMempool, useRealtimeStats } from '../contexts/WebSocketContext';
import ConnectionStatus from '../components/ConnectionStatus';
import Pagination from '../components/Pagination';
import { truncateHash, formatSynor, cn } from '../lib/utils';
import type { ExplorerTransaction } from '../lib/types';

export default function Mempool() {
  const [page, setPage] = useState(1);
  const [flashTx, setFlashTx] = useState<string | null>(null);

  // API data
  const { data: mempoolData, isLoading, error } = useMempool(page, 25);

  // Real-time updates
  const { latestTx, txHistory, isConnected } = useRealtimeMempool(50);
  const { stats: realtimeStats } = useRealtimeStats();

  // Convert mempool event to transaction format
  const convertMempoolTx = (tx: typeof latestTx): Partial<ExplorerTransaction> | null => {
    if (!tx) return null;
    return {
      id: tx.txId,
      hash: tx.txId,
      fee: tx.fee,
      mass: tx.mass,
      version: 0,
      inputs: [],
      outputs: [],
      totalInput: 0,
      totalOutput: 0,
      isCoinbase: false,
    };
  };

  // Merge API data with real-time updates (only on page 1)
  const mergedTransactions = useMemo(() => {
    const apiTxs = mempoolData?.data || [];

    if (page !== 1 || !txHistory.length) return apiTxs;

    // Convert real-time transactions
    const realtimeTxs = txHistory
      .map(convertMempoolTx)
      .filter((t): t is Partial<ExplorerTransaction> => t !== null);

    // Merge with deduplication
    const seen = new Set(realtimeTxs.map((t) => t.id));
    const merged = [...realtimeTxs];

    for (const tx of apiTxs) {
      if (!seen.has(tx.id)) {
        merged.push(tx);
        seen.add(tx.id);
      }
    }

    return merged.slice(0, 25);
  }, [mempoolData, txHistory, page]);

  // Flash effect for new transactions
  useEffect(() => {
    if (latestTx) {
      setFlashTx(latestTx.txId);
      const timer = setTimeout(() => setFlashTx(null), 1000);
      return () => clearTimeout(timer);
    }
  }, [latestTx]);

  const mempoolSize = realtimeStats?.mempoolSize ?? mempoolData?.total ?? 0;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="relative">
        <div className="absolute -top-10 left-0 w-[300px] h-[150px] bg-amber-500/10 rounded-full blur-[80px] pointer-events-none" />

        <div className="relative flex flex-col md:flex-row md:items-center justify-between gap-4">
          <div className="flex items-center gap-4">
            <div className="p-3 rounded-xl bg-gradient-to-br from-amber-500/20 to-orange-500/20 border border-amber-500/30">
              <Layers size={28} className="text-amber-400" />
            </div>
            <div>
              <h1 className="text-2xl md:text-3xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
                Mempool
              </h1>
              <p className="text-sm text-gray-400 mt-1">
                {mempoolSize.toLocaleString()} pending transactions
              </p>
            </div>
          </div>

          {/* Live indicator and connection status */}
          <div className="flex items-center gap-3">
            {isConnected && latestTx && (
              <div className="hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-lg bg-amber-500/10 border border-amber-500/30 text-amber-400 text-xs">
                <Radio size={12} className="animate-pulse" />
                <span>New tx: {truncateHash(latestTx.txId, 6)}</span>
              </div>
            )}
            <ConnectionStatus size="sm" />
          </div>
        </div>
      </div>

      {/* Stats cards */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <StatCard
          icon={<Layers size={20} className="text-amber-400" />}
          label="Pending Txs"
          value={mempoolSize.toLocaleString()}
          color="amber"
        />
        <StatCard
          icon={<Zap size={20} className="text-green-400" />}
          label="Tx/sec (avg)"
          value={latestTx ? '~1.0' : '0.0'}
          color="green"
        />
        <StatCard
          icon={<Coins size={20} className="text-synor-400" />}
          label="Avg Fee"
          value={latestTx ? formatSynor(latestTx.fee, 4) : '-'}
          color="synor"
        />
        <StatCard
          icon={<TrendingUp size={20} className="text-blue-400" />}
          label="Trend"
          value={mempoolSize > 50 ? 'Growing' : 'Stable'}
          color="blue"
        />
      </div>

      {/* Error state */}
      {error && (
        <div className="card p-6 text-red-400">
          Error loading mempool: {error.message}
        </div>
      )}

      {/* Transaction list */}
      {isLoading && !mergedTransactions.length ? (
        <MempoolSkeleton />
      ) : (
        <div className="card overflow-hidden">
          <div className="card-header flex items-center justify-between">
            <h2 className="font-semibold flex items-center gap-2">
              <Clock size={18} className="text-gray-400" />
              Pending Transactions
            </h2>
            {isConnected && (
              <span className="text-xs text-green-400 flex items-center gap-1">
                <span className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
                Live
              </span>
            )}
          </div>

          <div className="divide-y divide-gray-800">
            {mergedTransactions.length === 0 ? (
              <div className="p-8 text-center text-gray-500">
                No pending transactions in mempool
              </div>
            ) : (
              mergedTransactions.map((tx) => {
                const isFlashing = tx.id === flashTx;
                return (
                  <div
                    key={tx.id}
                    className={cn(
                      'p-4 hover:bg-gray-800/50 transition-all duration-500',
                      isFlashing && 'bg-amber-500/20 animate-pulse'
                    )}
                  >
                    <div className="flex items-start justify-between gap-4">
                      <div className="flex-1 min-w-0">
                        <Link
                          to={`/tx/${tx.id}`}
                          className={cn(
                            'font-mono text-sm hover:text-synor-300 transition-colors',
                            isFlashing ? 'text-amber-300 font-semibold' : 'text-synor-400'
                          )}
                        >
                          {truncateHash(tx.id || '', 12, 12)}
                        </Link>
                        <div className="flex items-center gap-4 mt-2 text-sm">
                          {'inputs' in tx && tx.inputs?.length ? (
                            <div className="flex items-center gap-2 text-gray-400">
                              <span>{tx.inputs.length} input{tx.inputs.length !== 1 ? 's' : ''}</span>
                              <ArrowRight size={14} />
                              <span>{tx.outputs?.length || 0} output{(tx.outputs?.length || 0) !== 1 ? 's' : ''}</span>
                            </div>
                          ) : (
                            <span className="text-gray-500 text-xs">Pending validation...</span>
                          )}
                        </div>
                      </div>
                      <div className="text-right">
                        {tx.fee !== undefined && tx.fee > 0 && (
                          <div className="text-sm text-amber-400 font-mono">
                            Fee: {formatSynor(tx.fee, 4)}
                          </div>
                        )}
                        {tx.mass !== undefined && tx.mass > 0 && (
                          <div className="text-xs text-gray-500 mt-1">
                            Mass: {tx.mass.toLocaleString()}
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                );
              })
            )}
          </div>
        </div>
      )}

      {/* Pagination */}
      {mempoolData && mempoolData.totalPages > 1 && (
        <Pagination
          page={page}
          totalPages={mempoolData.totalPages}
          hasNext={mempoolData.hasNext}
          hasPrev={mempoolData.hasPrev}
          onPageChange={setPage}
        />
      )}
    </div>
  );
}

function StatCard({
  icon,
  label,
  value,
  color,
}: {
  icon: React.ReactNode;
  label: string;
  value: string;
  color: 'amber' | 'green' | 'synor' | 'blue';
}) {
  const colorClasses = {
    amber: 'from-amber-500/20 to-orange-500/10 border-amber-500/30',
    green: 'from-green-500/20 to-emerald-500/10 border-green-500/30',
    synor: 'from-synor-500/20 to-violet-500/10 border-synor-500/30',
    blue: 'from-blue-500/20 to-cyan-500/10 border-blue-500/30',
  };

  return (
    <div
      className={cn(
        'relative overflow-hidden rounded-xl border p-4 bg-gradient-to-br',
        colorClasses[color]
      )}
    >
      <div className="flex items-center gap-3">
        {icon}
        <div>
          <div className="text-xs text-gray-400">{label}</div>
          <div className="text-lg font-semibold text-white">{value}</div>
        </div>
      </div>
    </div>
  );
}

function MempoolSkeleton() {
  return (
    <div className="card overflow-hidden animate-pulse">
      <div className="card-header">
        <div className="h-5 w-48 bg-gray-800 rounded" />
      </div>
      <div className="divide-y divide-gray-800">
        {Array.from({ length: 10 }).map((_, i) => (
          <div key={i} className="p-4 flex items-start justify-between gap-4">
            <div>
              <div className="h-4 w-48 bg-gray-800 rounded mb-2" />
              <div className="h-3 w-24 bg-gray-800 rounded" />
            </div>
            <div className="text-right">
              <div className="h-4 w-20 bg-gray-800 rounded mb-1" />
              <div className="h-3 w-16 bg-gray-800 rounded" />
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
