import { useCurrency } from '@/hooks/use-currency';
import { TOrderBookLevel } from '@/types/market.types';
import { CaretDownIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';

type CumLevel = TOrderBookLevel & { cumShares: number; cumTotal: number };

/**
 * Polymarket-style depth ladder for one outcome: asks stacked above bids with a
 * Last/Spread divider, PRICE · SHARES · TOTAL columns, cumulative-depth bars,
 * and Asks/Bids pills. Prices are already denominated for the selected outcome
 * by the parent (the API returns a single YES-denominated book).
 */
export default function OrderBook({
  asks,
  bids,
  outcomeLabel,
  lastPrice,
  onPick,
  levels = 8,
}: {
  asks: TOrderBookLevel[];
  bids: TOrderBookLevel[];
  outcomeLabel: string;
  lastPrice?: number;
  onPick?: (price: number) => void;
  levels?: number;
}) {
  const { t } = useTranslation();
  const { format } = useCurrency();
  const [collapsed, setCollapsed] = useState(false);

  const asksC = cumulate(asks.slice(0, levels));
  const bidsC = cumulate(bids.slice(0, levels));
  const maxCum = Math.max(
    1,
    ...asksC.map((l) => l.cumShares),
    ...bidsC.map((l) => l.cumShares),
  );

  const bestAsk = asks[0]?.price;
  const bestBid = bids[0]?.price;
  const spread =
    bestAsk != null && bestBid != null ? bestAsk - bestBid : undefined;

  const shares = (n: number) =>
    n.toLocaleString(undefined, { maximumFractionDigits: 2 });

  const row = (lvl: CumLevel, side: 'ask' | 'bid') => (
    <button
      key={`${side}-${lvl.price}`}
      type="button"
      onClick={() => onPick?.(lvl.price)}
      className="relative flex w-full items-center py-1 text-xs tabular-nums transition-colors hover:bg-black/[0.03] dark:hover:bg-white/[0.04]"
    >
      <span
        className={`absolute inset-y-0 left-0 ${side === 'ask' ? 'bg-pm-no-soft' : 'bg-pm-yes-soft'}`}
        style={{ width: `${(lvl.cumShares / maxCum) * 100}%` }}
      />
      <div className="relative ml-auto grid w-[64%] grid-cols-3 gap-2 px-3 text-right">
        <span
          className={`text-left font-semibold ${side === 'ask' ? 'text-pm-no' : 'text-pm-yes'}`}
        >
          {format(lvl.price)}
        </span>
        <span className="text-black/70 dark:text-white/70">
          {shares(lvl.shares)}
        </span>
        <span className="text-black/50 dark:text-white/50">
          {format(lvl.cumTotal)}
        </span>
      </div>
    </button>
  );

  const empty = asksC.length === 0 && bidsC.length === 0;

  return (
    <div className="overflow-hidden rounded-xl border border-black/5 dark:border-white/10">
      {/* Header: TRADE <outcome> + column labels */}
      <div className="flex items-center border-b border-black/5 px-3 py-2 dark:border-white/10">
        <button
          type="button"
          onClick={() => setCollapsed((c) => !c)}
          className="flex items-center gap-1 text-xs font-semibold tracking-wide text-black/70 uppercase dark:text-white/70"
        >
          {t('Trade')} {outcomeLabel}
          <CaretDownIcon
            weight="bold"
            className={`size-3.5 transition-transform ${collapsed ? '-rotate-90' : ''}`}
          />
        </button>
        <div className="ml-auto grid w-[64%] grid-cols-3 gap-2 px-3 text-right text-[11px] font-medium tracking-wide text-black/40 uppercase dark:text-white/40">
          <span className="text-left">{t('Price')}</span>
          <span>{t('Shares')}</span>
          <span>{t('Total')}</span>
        </div>
      </div>

      {collapsed ? null : empty ? (
        <p className="py-6 text-center text-xs text-black/40 dark:text-white/40">
          {t('No open orders yet.')}
        </p>
      ) : (
        <>
          {/* Asks (highest price on top, best ask nearest the spread) */}
          <div className="relative flex flex-col-reverse">
            {asksC.map((l) => row(l, 'ask'))}
            {asksC.length > 0 && (
              <span className="pointer-events-none absolute bottom-1 left-2 rounded-md bg-pm-no px-1.5 py-0.5 text-[10px] font-semibold text-white">
                {t('Asks')}
              </span>
            )}
          </div>

          {/* Last / Spread divider */}
          <div className="flex items-center justify-center gap-4 border-y border-black/5 bg-black/[0.02] py-1.5 text-[11px] text-black/50 dark:border-white/10 dark:bg-white/[0.03] dark:text-white/50">
            {lastPrice != null && (
              <span>
                {t('Last')}:{' '}
                <span className="font-medium text-black/70 dark:text-white/70">
                  {format(lastPrice)}
                </span>
              </span>
            )}
            {spread != null && (
              <span>
                {t('Spread')}:{' '}
                <span className="font-medium text-black/70 dark:text-white/70">
                  {format(spread)}
                </span>
              </span>
            )}
          </div>

          {/* Bids (best bid on top, nearest the spread) */}
          <div className="relative flex flex-col">
            {bidsC.length > 0 && (
              <span className="pointer-events-none absolute top-1 left-2 z-10 rounded-md bg-pm-yes px-1.5 py-0.5 text-[10px] font-semibold text-white">
                {t('Bids')}
              </span>
            )}
            {bidsC.map((l) => row(l, 'bid'))}
          </div>
        </>
      )}
    </div>
  );
}

/** Running cumulative shares + dollar total from the best (inner) level outward. */
function cumulate(levels: TOrderBookLevel[]): CumLevel[] {
  let cumShares = 0;
  let cumTotal = 0;

  return levels.map((l) => {
    cumShares += l.shares;
    cumTotal += l.price * l.shares;

    return { ...l, cumShares, cumTotal };
  });
}
