import { useEffect, type ReactNode } from 'react';
import { useDbisSwap } from './useDbisSwap';
import { formatAmountFromWei } from '../../config/dex';
import NasaPageHeader from '../omnl-dashboard/NasaPageHeader';
import NasaIcon from '../../components/icons/NasaIcon';

function TokenSelect({
  label,
  value,
  onChange,
  tokens,
}: {
  label: string;
  value: { symbol: string; address: string };
  onChange: (t: (typeof tokens)[0]) => void;
  tokens: ReturnType<typeof useDbisSwap>['tokens'];
}) {
  return (
    <label className="block">
      <span className="dash-stat-label mb-1 block">{label}</span>
      <select
        className="nasa-select"
        value={value.address}
        onChange={(e) => {
          const t = tokens.find((x) => x.address === e.target.value);
          if (t) onChange(t);
        }}
      >
        {tokens.map((t) => (
          <option key={t.address} value={t.address}>
            {t.symbol} — {t.name}
          </option>
        ))}
      </select>
    </label>
  );
}

function SidePanel({
  title,
  icon,
  children,
}: {
  title: string;
  icon: 'ledger' | 'rocket' | 'rail' | 'chart' | 'satellite';
  children: ReactNode;
}) {
  return (
    <div className="dash-card">
      <h3 className="dash-section-title mb-3 flex items-center gap-2">
        <NasaIcon name={icon} size={14} className="nasa-icon--telemetry" />
        {title}
      </h3>
      {children}
    </div>
  );
}

export default function DBISSwapPanel() {
  const swap = useDbisSwap();

  useEffect(() => {
    swap.loadMonitor();
  }, [swap.loadMonitor]);

  useEffect(() => {
    if (swap.isConnected) swap.loadLedgers();
  }, [swap.isConnected, swap.address, swap.loadLedgers]);

  const outDisplay =
    swap.plan?.amountOut && swap.tokenOut
      ? formatAmountFromWei(String(swap.plan.amountOut), swap.tokenOut.decimals)
      : swap.plan?.plannerResponse?.routePlan?.minAmountOut
        ? formatAmountFromWei(String(swap.plan.plannerResponse.routePlan.minAmountOut), swap.tokenOut.decimals)
        : '—';

  return (
    <div className="nasa-page px-4 py-6 max-w-6xl mx-auto">
      <NasaPageHeader
        icon="swap"
        missionId="SWP-138"
        title="Digital Swap Console"
        subtitle={`M2 asset exchange · Office 24 · ${swap.tokens.length} registered tokens`}
        badges={<span className="nasa-badge nasa-badge--telemetry">Chain 138</span>}
      />

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <div className="lg:col-span-2 dash-card">
          <div className="space-y-4">
            <TokenSelect label="Source asset" value={swap.tokenIn} onChange={swap.setTokenIn} tokens={swap.tokens} />
            <div className="flex justify-center">
              <button
                type="button"
                className="nasa-btn !rounded-full !p-2.5"
                onClick={() => {
                  const a = swap.tokenIn;
                  swap.setTokenIn(swap.tokenOut);
                  swap.setTokenOut(a);
                }}
                aria-label="Invert swap pair"
              >
                <NasaIcon name="swap" size={18} />
              </button>
            </div>
            <TokenSelect label="Target asset" value={swap.tokenOut} onChange={swap.setTokenOut} tokens={swap.tokens} />

            <label className="block">
              <span className="dash-stat-label mb-1 block">Amount</span>
              <input
                type="text"
                inputMode="decimal"
                placeholder="0.0"
                value={swap.amountIn}
                onChange={(e) => swap.setAmountIn(e.target.value)}
                className="nasa-input !min-h-[56px] !text-2xl"
              />
            </label>

            <div className="flex items-center gap-3 text-sm font-mono">
              <span className="text-[#7a9bb8] uppercase text-xs">Slippage</span>
              {[25, 50, 100].map((bps) => (
                <button
                  key={bps}
                  type="button"
                  className={`px-3 py-1 text-xs border font-mono ${
                    swap.slippageBps === bps
                      ? 'border-[#00d4ff] text-[#00d4ff] bg-[#00d4ff]/10'
                      : 'border-[#1e4a8a] text-[#7a9bb8]'
                  }`}
                  onClick={() => swap.setSlippageBps(bps)}
                >
                  {(bps / 100).toFixed(2)}%
                </button>
              ))}
            </div>

            <div className="nasa-inset-panel">
              <p className="dash-stat-label">Expected output</p>
              <p className="dash-stat-value !text-2xl">
                {outDisplay} <span className="text-base text-[#00d4ff]">{swap.tokenOut.symbol}</span>
              </p>
              {swap.plan?.plannerResponse?.routePlan?.legs && (
                <p className="text-xs text-[#7a9bb8] mt-2 font-mono">
                  Route:{' '}
                  {swap.plan.plannerResponse.routePlan.legs
                    .map((l: { provider?: string }) => l.provider)
                    .filter(Boolean)
                    .join(' → ')}
                </p>
              )}
            </div>

            {swap.error && (
              <p className="text-sm text-[#fc3d21] flex items-center gap-1">
                <NasaIcon name="alert" size={14} />
                {swap.error}
              </p>
            )}
            {swap.txHash && (
              <p className="text-xs text-[#7a9bb8] break-all font-mono">
                Tx:{' '}
                <a href={`https://explorer.d-bis.org/tx/${swap.txHash}`} target="_blank" rel="noreferrer" className="text-[#00d4ff] hover:underline">
                  {swap.txHash}
                </a>
              </p>
            )}

            <div className="flex gap-3 pt-2">
              <button type="button" className="nasa-btn flex-1" disabled={swap.loading || !swap.amountIn} onClick={() => swap.fetchPlan()}>
                <NasaIcon name="chart" size={14} />
                {swap.loading ? 'Computing…' : 'Get quote'}
              </button>
              <button
                type="button"
                className="nasa-btn nasa-btn--primary flex-1"
                disabled={swap.loading || !swap.isConnected || !swap.amountIn}
                onClick={() => swap.executeSwap()}
              >
                <NasaIcon name="wallet" size={14} />
                {!swap.isConnected ? 'Connect wallet' : swap.loading ? 'Executing…' : 'Execute swap'}
              </button>
            </div>
          </div>
        </div>

        <div className="space-y-4">
          <SidePanel title="Office 24 ledger" icon="ledger">
            {!swap.isConnected ? (
              <p className="text-sm text-[#7a9bb8]">Connect wallet for crypto balances</p>
            ) : swap.ledger ? (
              <div className="text-xs space-y-2 font-mono">
                <p>M1: {(swap.ledger as { fundLedger?: { M1?: { circulating?: string } } }).fundLedger?.M1?.circulating ?? '—'}</p>
                <p>M2: {(swap.ledger as { fundLedger?: { M2?: { broadMoney?: string } } }).fundLedger?.M2?.broadMoney ?? '—'}</p>
                {(swap.ledger as { cryptoLedger?: { balances?: Record<string, string> } }).cryptoLedger?.balances && (
                  <div className="mt-2 pt-2 border-t border-[#1e4a8a]">
                    <p className="text-[#7a9bb8] mb-1">Wallet balances</p>
                    {Object.entries(
                      (swap.ledger as { cryptoLedger: { balances: Record<string, string> } }).cryptoLedger.balances,
                    ).map(([sym, bal]) => (
                      <p key={sym}>{sym}: {Number(bal).toFixed(4)}</p>
                    ))}
                  </div>
                )}
              </div>
            ) : (
              <button type="button" className="nasa-btn w-full text-xs" onClick={() => swap.loadLedgers()}>
                Load ledgers
              </button>
            )}
          </SidePanel>

          <SidePanel title="M2 token load" icon="rocket">
            <p className="text-xs text-[#7a9bb8] mb-3">GL 2200 → on-chain M2</p>
            <input type="text" inputMode="decimal" placeholder="Fiat amount" value={swap.loadAmount} onChange={(e) => swap.setLoadAmount(e.target.value)} className="nasa-input mb-2 text-sm" />
            <button type="button" className="nasa-btn nasa-btn--primary w-full text-xs" disabled={swap.loading || !swap.isConnected || !swap.loadAmount} onClick={() => swap.loadM2Token()}>
              Load {swap.tokenOut.symbol}
            </button>
          </SidePanel>

          <SidePanel title="Transfer" icon="rail">
            <input type="text" placeholder="Recipient 0x…" value={swap.transferTo} onChange={(e) => swap.setTransferTo(e.target.value)} className="nasa-input mb-2 text-sm" />
            <input type="text" inputMode="decimal" placeholder="Amount" value={swap.transferAmount} onChange={(e) => swap.setTransferAmount(e.target.value)} className="nasa-input mb-2 text-sm" />
            <button type="button" className="nasa-btn w-full text-xs mb-2" disabled={swap.loading || !swap.isConnected} onClick={() => swap.internalTransfer()}>
              Internal transfer
            </button>
            <input type="text" placeholder="External IBAN (SWIFT)" value={swap.externalIban} onChange={(e) => swap.setExternalIban(e.target.value)} className="nasa-input mb-2 text-sm" />
            <button type="button" className="nasa-btn w-full text-xs" disabled={swap.loading || !swap.isConnected || !swap.externalIban} onClick={() => swap.externalTransfer()}>
              External (SWIFT)
            </button>
          </SidePanel>

          {swap.lastSettlement && (
            <SidePanel title="Last settlement" icon="satellite">
              <p className="text-xs text-[#7a9bb8] font-mono break-all">
                {(swap.lastSettlement as { phase?: string }).phase ?? 'OK'} · {(swap.lastSettlement as { settlementId?: string }).settlementId ?? '—'}
              </p>
            </SidePanel>
          )}

          <SidePanel title="Swap monitor" icon="chart">
            {swap.monitor ? (
              <div className="text-xs space-y-2 font-mono">
                <p>Total: {(swap.monitor as { stats?: { total?: number } }).stats?.total ?? 0} · 24h: {(swap.monitor as { stats?: { last24h?: number } }).stats?.last24h ?? 0}</p>
                <ul className="max-h-40 overflow-y-auto space-y-1 text-[#7a9bb8]">
                  {((swap.monitor as { swaps?: { tokenIn: string; status: string; createdAt: string }[] }).swaps ?? []).slice(0, 5).map((s, i) => (
                    <li key={i} className="truncate">{s.status} · {s.createdAt.slice(0, 16)}</li>
                  ))}
                </ul>
              </div>
            ) : (
              <p className="text-xs text-[#7a9bb8]">Loading telemetry…</p>
            )}
          </SidePanel>
        </div>
      </div>
    </div>
  );
}
