import type { ReactNode } from 'react';
import type { Balances } from './shared';
import { ArrowDownLeft, ArrowUpRight, Bitcoin, Clock, Loader2, Zap } from 'lucide-react';
import { Link } from 'react-router';
import { KIND_LABELS, walletSectionPath } from './shared';
import { formatSats, formatTimestamp, truncateMiddle } from './format';
import { Amount, UnitToggle } from './Amount';
import { EmptyWallet } from './EmptyWallet';
import { SyncBadge } from './SyncBadge';
import { useSelectedWallet } from './useSelectedWallet';
import { useBalances, useCapabilities, useTransactions, useWalletInfo } from './useWalletData';

// The at-a-glance section: what you hold, whether the node agrees with the chain, and the last few moves.
//
// Every number here is a read, so the whole screen works against a locked wallet — which is its resting
// state. Nothing on this page prompts for a passphrase.

/**
 * The sub-line under the on-chain figure. Unconfirmed and frozen are both reasons the headline number is
 * not what a send can use, and both can be true at once, so they read as a list rather than a choice.
 */
function onchainHint(balances: Balances | null | undefined): string | undefined {
  if (!balances) return undefined;
  const parts: string[] = [];
  if (balances.onchainUnconfirmed !== 0) {
    const sign = balances.onchainUnconfirmed > 0 ? '+' : '';
    parts.push(`${sign}${formatSats(balances.onchainUnconfirmed)} sats unconfirmed`);
  }
  if (balances.onchainFrozen > 0) parts.push(`${formatSats(balances.onchainFrozen)} sats frozen`);
  return parts.length ? parts.join(' · ') : undefined;
}

export const OverviewView = () => {
  const { wallet, walletId, isLoading } = useSelectedWallet();
  const { capabilities } = useCapabilities(walletId);
  const { balances, sync, isLoading: balancesLoading } = useBalances(walletId);
  const { info } = useWalletInfo(walletId);
  const { transactions } = useTransactions(walletId, 5);

  if (!walletId) return <EmptyWallet isLoading={isLoading} />;

  const hasLightning = balances?.lightningBalance != null;
  const canSend = capabilities.includes('onchainSend') || capabilities.includes('lightningSend');
  const canReceive = capabilities.includes('onchainReceive') || capabilities.includes('lightningReceive');

  return (
    <div className="h-full overflow-y-auto p-4">
      <div className="mb-3 flex items-center justify-between">
        <div className="min-w-0">
          <h2 className="truncate text-sm font-semibold">{wallet?.name}</h2>
          <p className="truncate text-xs text-muted-foreground">
            {wallet ? KIND_LABELS[wallet.kind] : '—'}
            {info?.alias && ` · ${info.alias}`}
            {info?.version && ` · ${info.version}`}
          </p>
        </div>
        <div className="flex shrink-0 items-center gap-2">
          <SyncBadge sync={sync} />
          <UnitToggle />
        </div>
      </div>

      {balancesLoading && !balances ? (
        <div className="flex items-center gap-2 py-8 text-sm text-muted-foreground">
          <Loader2 className="h-4 w-4 animate-spin" />
          Reading balances…
        </div>
      ) : (
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
          <Tile
            icon={<Bitcoin className="h-4 w-4 text-orange-500" />}
            label="On-chain"
            value={<Amount sats={balances?.onchainConfirmed ?? null} className="text-xl font-semibold" />}
            hint={onchainHint(balances)}
          />
          {hasLightning && (
            <Tile
              icon={<Zap className="h-4 w-4 text-amber-500" />}
              label="Lightning"
              value={<Amount sats={balances?.lightningBalance ?? null} className="text-xl font-semibold" />}
              hint={
                balances?.lightningInbound != null ? `${formatSats(balances.lightningInbound)} sats inbound` : undefined
              }
            />
          )}
          <Tile
            label="Block height"
            value={
              <span className="text-xl font-semibold tabular-nums">{info?.blockHeight?.toLocaleString() ?? '—'}</span>
            }
            hint={info ? (info.synced ? 'synced' : 'syncing…') : undefined}
          />
          <Tile
            label="Network"
            value={<span className="text-xl font-semibold">{info?.network ?? wallet?.network ?? '—'}</span>}
            hint={info?.pubkey ? truncateMiddle(info.pubkey, 8, 6) : undefined}
          />
        </div>
      )}

      {(canReceive || canSend) && (
        <div className="mt-4 flex gap-2">
          {canReceive && (
            <Link
              to={walletSectionPath('receive', walletId)}
              className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-xs font-medium transition-colors hover:bg-muted"
            >
              <ArrowDownLeft className="h-3.5 w-3.5 text-emerald-500" />
              Receive
            </Link>
          )}
          {canSend && (
            <Link
              to={walletSectionPath('send', walletId)}
              className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-xs font-medium transition-colors hover:bg-muted"
            >
              <ArrowUpRight className="h-3.5 w-3.5 text-destructive" />
              Send
            </Link>
          )}
        </div>
      )}

      <section className="mt-4 rounded-xl border border-border p-4">
        <div className="mb-3 flex items-center justify-between">
          <h3 className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">Recent activity</h3>
          <Link to={walletSectionPath('transactions', walletId)} className="text-[11px] text-primary hover:underline">
            all transactions
          </Link>
        </div>
        {transactions.length === 0 ? (
          <p className="text-xs text-muted-foreground">Nothing yet.</p>
        ) : (
          <ul className="divide-y divide-border">
            {transactions.map((tx) => (
              <li key={tx.txid} className="flex items-center gap-3 py-2">
                <span
                  className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-full ${
                    tx.amount < 0 ? 'bg-destructive/10' : 'bg-emerald-500/10'
                  }`}
                >
                  {tx.amount < 0 ? (
                    <ArrowUpRight className="h-3 w-3 text-destructive" />
                  ) : (
                    <ArrowDownLeft className="h-3 w-3 text-emerald-500" />
                  )}
                </span>
                <div className="min-w-0 flex-1">
                  <div className="truncate text-xs font-medium">{tx.label ?? truncateMiddle(tx.txid)}</div>
                  <div className="flex items-center gap-1 text-[11px] text-muted-foreground">
                    {tx.confirmations <= 0 && <Clock className="h-3 w-3" />}
                    {tx.confirmations <= 0 ? 'pending' : formatTimestamp(tx.timestamp)}
                  </div>
                </div>
                <Amount sats={tx.amount} signed className="shrink-0 text-xs" />
              </li>
            ))}
          </ul>
        )}
      </section>
    </div>
  );
};

type TileProps = { label: string; value: ReactNode; hint?: string; icon?: ReactNode };

const Tile = ({ label, value, hint, icon }: TileProps) => (
  <div className="rounded-xl border border-border p-4">
    <div className="flex items-center gap-1.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
      {icon}
      {label}
    </div>
    <div className="mt-1">{value}</div>
    {hint && (
      <div className="mt-0.5 truncate text-xs text-muted-foreground" title={hint}>
        {hint}
      </div>
    )}
  </div>
);
