"use client";

import { useEffect, useState, useTransition } from "react";

import { DataTable } from "@/components/data-table";
import { MetricCard } from "@/components/metric-card";
import { SectionHeading } from "@/components/section-heading";
import {
  getExecutionAccounts,
  getExecutionBalances,
  getExecutionFills,
  getExecutionHealth,
  getExecutionMarkets,
  getExecutionOrders,
  getExecutionPositions,
  getExecutionVenues,
  postExecutionCancel,
  postExecutionCancelAll,
  postExecutionOrder,
  postExecutionQuote,
} from "@/lib/api/client";
import { formatTimestamp } from "@/lib/format";
import type {
  ExecutionAccountSummary,
  ExecutionActionResponse,
  ExecutionBalanceRecord,
  ExecutionFillRecord,
  ExecutionHealthRecord,
  ExecutionMarketSummary,
  ExecutionOrderRecord,
  ExecutionPositionRecord,
  ExecutionVenueSummary,
} from "@/lib/api/types";

import { EXECUTION_SECTIONS } from "./execution-config";

type ExecutionSnapshot = {
  venues: ExecutionVenueSummary[];
  accounts: ExecutionAccountSummary[];
  markets: ExecutionMarketSummary[];
  orders: ExecutionOrderRecord[];
  fills: ExecutionFillRecord[];
  positions: ExecutionPositionRecord[];
  balances: ExecutionBalanceRecord[];
  health: ExecutionHealthRecord[];
};

export function ExecutionWorkspace({
  section,
  initial,
  initialFilters,
}: {
  section: string;
  initial: ExecutionSnapshot;
  initialFilters?: {
    venue?: string;
    account?: string;
    asset?: string;
  };
}) {
  const config = EXECUTION_SECTIONS.find((item) => item.id === section) ?? EXECUTION_SECTIONS[0];
  const [snapshot, setSnapshot] = useState(initial);
  const [selectedVenue, setSelectedVenue] = useState(
    initialFilters?.venue ?? initial.venues[0]?.venue ?? "hyperliquid",
  );
  const [selectedAccount, setSelectedAccount] = useState(
    initialFilters?.account ?? initial.accounts[0]?.label ?? "",
  );
  const [asset, setAsset] = useState(initialFilters?.asset ?? "BTC");
  const [symbol, setSymbol] = useState("BTC-PERP");
  const [side, setSide] = useState("buy");
  const [orderType, setOrderType] = useState("limit");
  const [mode, setMode] = useState("dry_run");
  const [size, setSize] = useState("1");
  const [price, setPrice] = useState("");
  const [actionResult, setActionResult] = useState<ExecutionActionResponse | null>(null);
  const [pending, startTransition] = useTransition();

  async function refresh() {
    startTransition(async () => {
      const [venues, accounts, markets, orders, fills, positions, balances, health] = await Promise.all([
        getExecutionVenues(),
        getExecutionAccounts(),
        getExecutionMarkets(selectedVenue, asset),
        getExecutionOrders({ venue: selectedVenue, account: selectedAccount, asset, limit: 50 }),
        getExecutionFills({ venue: selectedVenue, account: selectedAccount, asset, limit: 50 }),
        getExecutionPositions({ venue: selectedVenue, account: selectedAccount, asset }),
        getExecutionBalances({ venue: selectedVenue, account: selectedAccount }),
        getExecutionHealth(),
      ]);
      setSnapshot({ venues, accounts, markets, orders, fills, positions, balances, health });
    });
  }

  useEffect(() => {
    void refresh();
  }, [selectedVenue, selectedAccount, asset]);

  const onlineHealth = snapshot.health.filter((item) => item.status === "online");
  const venueCapabilities = snapshot.venues.find((item) => item.venue === selectedVenue);
  const orderRows = snapshot.orders.map((item) => ({
    ts: formatTimestamp(item.ts),
    venue: item.venue,
    account: item.account,
    asset: item.asset,
    symbol: item.symbol,
    event_type: item.event_type,
    status: item.status,
    side: item.side,
    order_type: item.order_type,
    price: item.price,
    size: item.size,
    reason: item.reason,
  }));
  const fillRows = snapshot.fills.map((item) => ({
    ts: formatTimestamp(item.ts),
    venue: item.venue,
    account: item.account,
    asset: item.asset,
    symbol: item.symbol,
    side: item.side,
    price: item.price,
    size: item.size,
    fee: item.fee,
    liquidity: item.liquidity,
    quality_flag: item.quality_flag,
  }));
  const positionRows = snapshot.positions.map((item) => ({
    ts: formatTimestamp(item.ts),
    venue: item.venue,
    account: item.account,
    asset: item.asset,
    symbol: item.symbol,
    quantity: item.quantity,
    entry_price: item.entry_price,
    mark_price: item.mark_price,
    unrealized_pnl: item.unrealized_pnl,
    leverage: item.leverage,
    quality_flag: item.quality_flag,
  }));
  const balanceRows = snapshot.balances.map((item) => ({
    ts: formatTimestamp(item.ts),
    venue: item.venue,
    account: item.account,
    asset: item.asset,
    balance_type: item.balance_type,
    total: item.total,
    available: item.available,
    locked: item.locked,
    quality_flag: item.quality_flag,
  }));
  const marketRows = snapshot.markets.map((item) => ({
    ts: formatTimestamp(item.ts),
    venue: item.venue,
    asset: item.asset,
    symbol: item.symbol,
    instrument_type: item.instrument_type,
    status: item.status,
    best_bid: item.best_bid,
    best_ask: item.best_ask,
    mark_price: item.mark_price,
    quality_flag: item.quality_flag,
  }));
  const healthRows = snapshot.health.map((item) => ({
    venue: item.venue,
    account: item.account,
    status: item.status,
    ws_connected: item.ws_connected,
    private_ws_connected: item.private_ws_connected,
    latency_ms: item.latency_ms,
    last_heartbeat_ms: item.last_heartbeat_ms,
    reconnect_count: item.reconnect_count,
    last_error: item.last_error,
  }));

  async function runOrderAction(action: "quote" | "order" | "cancel" | "cancel_all") {
    const common = {
      venue: selectedVenue,
      account: selectedAccount,
      asset,
      symbol,
      mode,
    };
    let result: ExecutionActionResponse | null = null;
    if (action === "quote") {
      result = await postExecutionQuote({
        ...common,
        side,
        size: Number(size),
      });
    } else if (action === "order") {
      result = await postExecutionOrder({
        ...common,
        instrument_type: selectedVenue === "bebop" ? "spot" : selectedVenue === "derive" ? "option" : "perp",
        side,
        order_type: orderType,
        time_in_force: orderType === "ioc" ? "ioc" : "gtc",
        size: Number(size),
        price: price ? Number(price) : null,
      });
    } else if (action === "cancel") {
      const latestRequestId = snapshot.orders[0]?.request_id ?? null;
      result = await postExecutionCancel({ ...common, request_id: latestRequestId });
    } else {
      result = await postExecutionCancelAll(common);
    }
    setActionResult(result);
    await refresh();
  }

  return (
    <div className="pageStack">
      <SectionHeading kicker="Execution" title={config.title} description={config.description} />
      <div className="toolbar">
        <label>
          Venue
          <select value={selectedVenue} onChange={(event) => setSelectedVenue(event.target.value)}>
            {snapshot.venues.map((item) => (
              <option key={item.venue} value={item.venue}>{item.venue}</option>
            ))}
          </select>
        </label>
        <label>
          Account
          <select value={selectedAccount} onChange={(event) => setSelectedAccount(event.target.value)}>
            {snapshot.accounts.map((item) => (
              <option key={item.label} value={item.label}>{item.label}</option>
            ))}
          </select>
        </label>
        <label>
          Asset
          <select value={asset} onChange={(event) => setAsset(event.target.value)}>
            <option value="BTC">BTC</option>
            <option value="ETH">ETH</option>
          </select>
        </label>
        <button onClick={() => void refresh()} disabled={pending}>{pending ? "Refreshing…" : "Refresh"}</button>
      </div>

      <div className="gridCols4">
        <MetricCard label="Venues" value={String(snapshot.venues.length)} tone="ok" />
        <MetricCard label="Accounts" value={String(snapshot.accounts.length)} tone="neutral" />
        <MetricCard label="Online" value={String(onlineHealth.length)} tone={onlineHealth.length > 0 ? "ok" : "warn"} />
        <MetricCard
          label="Private WS"
          value={String(snapshot.health.filter((item) => item.private_ws_connected).length)}
          tone="neutral"
        />
      </div>

      {section === "order-entry" ? (
        <div className="twoCol">
          <div className="panel">
            <div className="panelHeader"><h3>Operator ticket</h3></div>
            <div className="toolbar" style={{ flexDirection: "column", alignItems: "stretch", gap: 10 }}>
              <label>
                Symbol
                <input value={symbol} onChange={(event) => setSymbol(event.target.value)} />
              </label>
              <label>
                Side
                <select value={side} onChange={(event) => setSide(event.target.value)}>
                  <option value="buy">buy</option>
                  <option value="sell">sell</option>
                </select>
              </label>
              <label>
                Order type
                <select value={orderType} onChange={(event) => setOrderType(event.target.value)}>
                  {(venueCapabilities?.supported_order_types ?? ["limit", "market"]).map((item) => (
                    <option key={item} value={item}>{item}</option>
                  ))}
                </select>
              </label>
              <label>
                Mode
                <select value={mode} onChange={(event) => setMode(event.target.value)}>
                  <option value="dry_run">dry_run</option>
                  <option value="paper">paper</option>
                  <option value="live">live</option>
                </select>
              </label>
              <label>
                Size
                <input value={size} onChange={(event) => setSize(event.target.value)} />
              </label>
              <label>
                Price
                <input value={price} onChange={(event) => setPrice(event.target.value)} placeholder="optional for market" />
              </label>
              <div className="toolbar">
                <button onClick={() => void runOrderAction("quote")} disabled={!selectedAccount}>Quote</button>
                <button onClick={() => void runOrderAction("order")} disabled={!selectedAccount}>Submit</button>
                <button onClick={() => void runOrderAction("cancel")} disabled={!selectedAccount}>Cancel latest</button>
                <button onClick={() => void runOrderAction("cancel_all")} disabled={!selectedAccount}>Cancel all</button>
              </div>
            </div>
          </div>
          <div className="panel">
            <div className="panelHeader"><h3>Validation output</h3></div>
            {actionResult ? (
              <div className="summaryList">
                <div><strong>Status</strong> {actionResult.status}</div>
                <div><strong>Mode</strong> {actionResult.mode}</div>
                <div><strong>Message</strong> {actionResult.message}</div>
                <div><strong>Request</strong> {actionResult.request_id}</div>
                <div><strong>Failure</strong> {actionResult.failure_code ?? "—"}</div>
              </div>
            ) : (
              <p style={{ color: "var(--text-dim)" }}>No execution action submitted yet.</p>
            )}
          </div>
        </div>
      ) : null}

      {section === "markets" && <DataTable columns={["ts", "venue", "asset", "symbol", "instrument_type", "status", "best_bid", "best_ask", "mark_price", "quality_flag"]} rows={marketRows} statusColumn="status" />}
      {section === "orders" && <DataTable columns={["ts", "venue", "account", "asset", "symbol", "event_type", "status", "side", "order_type", "price", "size", "reason"]} rows={orderRows} statusColumn="status" />}
      {section === "fills" && <DataTable columns={["ts", "venue", "account", "asset", "symbol", "side", "price", "size", "fee", "liquidity", "quality_flag"]} rows={fillRows} statusColumn="quality_flag" />}
      {section === "positions" && <DataTable columns={["ts", "venue", "account", "asset", "symbol", "quantity", "entry_price", "mark_price", "unrealized_pnl", "leverage", "quality_flag"]} rows={positionRows} statusColumn="quality_flag" />}
      {section === "balances" && <DataTable columns={["ts", "venue", "account", "asset", "balance_type", "total", "available", "locked", "quality_flag"]} rows={balanceRows} statusColumn="quality_flag" />}
      {section === "venue-health" && <DataTable columns={["venue", "account", "status", "ws_connected", "private_ws_connected", "latency_ms", "last_heartbeat_ms", "reconnect_count", "last_error"]} rows={healthRows} statusColumn="status" />}
      {section === "overview" && (
        <div className="panel">
          <div className="panelHeader"><h3>Execution summary</h3></div>
          <div className="summaryList">
            <li>
              <span>Selected venue</span>
              <strong>{selectedVenue}</strong>
            </li>
            <li>
              <span>Supported order types</span>
              <strong>{venueCapabilities?.supported_order_types.join(", ") ?? "—"}</strong>
            </li>
            <li>
              <span>Private connectivity</span>
              <strong>{snapshot.health.find((item) => item.venue === selectedVenue)?.private_ws_connected ? "connected" : "cold"}</strong>
            </li>
            <li>
              <span>Latest order event</span>
              <strong>{snapshot.orders[0] ? formatTimestamp(snapshot.orders[0].ts) : "n/a"}</strong>
            </li>
          </div>
        </div>
      )}

      <div className="panel">
        <div className="panelHeader"><h3>How to use this</h3></div>
        <div className="playbookGrid">
          <Playbook title="What it measures" items={config.playbook.whatItMeasures} />
          <Playbook title="Interpretation" items={config.playbook.interpretation} />
          <Playbook title="Workflow" items={config.playbook.workflow} />
          <Playbook title="Caveats" items={config.playbook.caveats} />
        </div>
      </div>
    </div>
  );
}

function Playbook({ title, items }: { title: string; items: string[] }) {
  return (
    <div className="playbookBlock">
      <h4>{title}</h4>
      <ul>
        {items.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
