import type { Utxo } from './shared';
import { Link } from 'react-router';
import { Loader2, Snowflake, Sun } from 'lucide-react';
import { formatConfirmations, truncateMiddle } from './format';
import { walletSectionPath } from './shared';
import { Amount } from './Amount';
import { EmptyWallet, UnsupportedSection } from './EmptyWallet';
import { SyncBadge } from './SyncBadge';
import { useSelectedWallet } from './useSelectedWallet';
import { useCoinSelection } from './useCoinSelection';
import { useCapabilities, useUtxos, useWalletOperations } from './useWalletData';

// Coin control. Works while locked: which coins exist and which are frozen is watch-only information, and
// freezing is Officer's own flag rather than anything signed.
//
// The selection lives in `?coins=` so the Send section reads the same set straight from the URL.

export const CoinsView = () => {
  const { walletId, isLoading } = useSelectedWallet();
  const { capabilities } = useCapabilities(walletId);
  const supported = capabilities.includes('coinControl');

  const { utxos, sync, isLoading: utxosLoading } = useUtxos(walletId, supported);
  const { selected, toggle, clear } = useCoinSelection();

  if (!walletId) return <EmptyWallet isLoading={isLoading} />;
  if (!supported) return <UnsupportedSection what="coin control" />;

  const selectedTotal = utxos
    .filter((u) => selected.includes(`${u.txid}:${u.vout}`))
    .reduce((sum, u) => sum + u.amountSats, 0);
  const spendableTotal = utxos.filter((u) => !u.frozen).reduce((sum, u) => sum + u.amountSats, 0);

  return (
    <div className="flex h-full flex-col">
      <div className="flex items-center gap-3 border-b border-border px-4 py-2 text-xs">
        <span className="text-muted-foreground">
          {utxos.length} coin{utxos.length === 1 ? '' : 's'} · <Amount sats={spendableTotal} /> spendable
        </span>
        <span className="flex-1" />
        <SyncBadge sync={sync} />
        {selected.length > 0 && (
          <>
            <span>
              {selected.length} selected · <Amount sats={selectedTotal} className="font-semibold" />
            </span>
            <button type="button" onClick={clear} className="text-primary hover:underline">
              clear
            </button>
            <Link
              to={walletSectionPath('send', walletId)}
              className="rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90"
            >
              Spend these
            </Link>
          </>
        )}
      </div>

      <div className="min-h-0 flex-1 overflow-y-auto">
        {utxosLoading && utxos.length === 0 ? (
          <div className="flex h-full items-center justify-center gap-2 text-sm text-muted-foreground">
            <Loader2 className="h-4 w-4 animate-spin" />
            Listing coins…
          </div>
        ) : utxos.length === 0 ? (
          <div className="flex h-full flex-col items-center justify-center gap-1 p-8 text-center">
            {/* "No coins" is only true if the chain was actually read. Never-synced is a different fact. */}
            <p className="text-sm font-medium">{sync && sync.syncedAt === null ? 'Coins unavailable' : 'No coins'}</p>
            <p className="text-xs text-muted-foreground">
              {sync && sync.syncedAt === null
                ? (sync.lastError ?? 'The chain source could not be reached.')
                : 'Receive something and it will show up here as a UTXO.'}
            </p>
          </div>
        ) : (
          <ul className="divide-y divide-border">
            {utxos.map((utxo) => (
              <CoinRow
                key={`${utxo.txid}:${utxo.vout}`}
                utxo={utxo}
                walletId={walletId}
                selected={selected.includes(`${utxo.txid}:${utxo.vout}`)}
                onToggle={toggle}
              />
            ))}
          </ul>
        )}
      </div>
    </div>
  );
};

type CoinRowProps = { utxo: Utxo; walletId: number; selected: boolean; onToggle: (outpoint: string) => void };

const CoinRow = ({ utxo, walletId, selected, onToggle }: CoinRowProps) => {
  const { freeze } = useWalletOperations(walletId);
  const outpoint = `${utxo.txid}:${utxo.vout}`;

  return (
    <li className={`flex items-center gap-3 px-4 py-2.5 ${utxo.frozen ? 'opacity-60' : ''}`}>
      <input
        type="checkbox"
        checked={selected}
        disabled={utxo.frozen}
        onChange={() => onToggle(outpoint)}
        aria-label={`Select ${outpoint}`}
        className="h-3.5 w-3.5 shrink-0 accent-primary"
      />

      <div className="min-w-0 flex-1">
        <div className="truncate text-xs font-medium">{utxo.label || truncateMiddle(utxo.address, 16, 10)}</div>
        <div className="mt-0.5 flex items-center gap-2 font-mono text-[10px] text-muted-foreground">
          <span>
            {truncateMiddle(utxo.txid, 10, 6)}:{utxo.vout}
          </span>
          <span className="font-sans">{formatConfirmations(utxo.confirmations)}</span>
          {utxo.addressType && <span className="font-sans">{utxo.addressType}</span>}
        </div>
      </div>

      <Amount sats={utxo.amountSats} className="shrink-0 text-xs font-semibold" />

      <button
        type="button"
        onClick={() => freeze.mutate({ outpoint, frozen: !utxo.frozen })}
        disabled={freeze.isPending}
        title={utxo.frozen ? 'Make this coin spendable again' : 'Keep this coin out of automatic selection'}
        className="shrink-0 text-muted-foreground transition-colors hover:text-foreground"
      >
        {utxo.frozen ? <Sun className="h-3.5 w-3.5" /> : <Snowflake className="h-3.5 w-3.5" />}
      </button>
    </li>
  );
};
