import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Separator } from "@/components/ui/separator";
import { Badge } from "@/components/ui/badge";
import { KeyRound, ShieldCheck, DollarSign, Percent, CheckCircle2, Zap, RefreshCw, Link2, Trash2, RotateCcw, Star, LayoutGrid, X as XIcon, ListOrdered, Gauge } from "lucide-react";
import { useTrendMatrixPrefs, MIN_COIN_COUNT, MAX_COIN_COUNT } from "@/lib/trend-matrix-prefs";
import { useApprovalMode, useTradeThreshold } from "@/lib/trade-approval";
import { useAutoExit } from "@/lib/auto-exit";
import { useSignalsPageSize, SIGNALS_PAGE_SIZE_OPTIONS, type SignalsPageSize, useTradeLimits, countTradesToday, useAllowedCoins, useRiskProfile } from "@/lib/user-prefs";
import { useAllowedRiskLevels, COIN_RISK_LEVELS, RISK_META } from "@/lib/coin-risk";
import {
  fetchDeltaAccount,
  loadCreds,
  saveCreds,
  clearCreds,
  type DeltaAccountResponse,
  type DeltaRegion,
} from "@/lib/delta-account";
import { fmtUsd } from "@/lib/mock-data";
import { IpBadge } from "@/components/ip-badge";
import { backendApi } from "@/lib/backend-client";
import { AlertRulesCard } from "@/components/alert-rules-card";
import { Zap as ZapIcon } from "lucide-react";

export const Route = createFileRoute("/_app/settings")({
  head: () => ({
    meta: [
      { title: "Settings · API Profile" },
      { name: "description", content: "Manage Delta Exchange API credentials and risk sizing rules." },
    ],
  }),
  component: Settings,
});

function Settings() {
  const [risk, setRisk] = useRiskProfile();
  const usePct = risk.sizingType === "PERCENTAGE";
  const setUsePct = (v: boolean) => setRisk({ sizingType: v ? "PERCENTAGE" : "FIXED_AMOUNT" });
  const pct = usePct ? risk.sizingValue : 2;
  const setPct = (n: number) => setRisk({ sizingType: "PERCENTAGE", sizingValue: n });
  const fixed = !usePct ? risk.sizingValue : 100;
  const setFixed = (n: number) => setRisk({ sizingType: "FIXED_AMOUNT", sizingValue: n });
  const leverage = risk.leverage;
  const setLeverage = (n: number) => setRisk({ leverage: n });
  const maxRisk = risk.maxRiskPct;
  const setMaxRisk = (n: number) => setRisk({ maxRiskPct: n });
  const [apiKey, setApiKey] = useState("");
  const [apiSecret, setApiSecret] = useState("");
  const [label, setLabel] = useState("");
  const [region, setRegion] = useState<DeltaRegion>("india");
  const [approvalMode, setApprovalMode] = useApprovalMode();
  const [tradeThreshold, setTradeThreshold] = useTradeThreshold();

  const [autoExit, updateAutoExit] = useAutoExit();
  const { favorites, coinCount, removeFavorite, setCoinCount } = useTrendMatrixPrefs();
  const [signalsPageSize, setSignalsPageSize] = useSignalsPageSize();
  const tradeLimits = useTradeLimits();
  const allowedCoins = useAllowedCoins();
  const riskLevels = useAllowedRiskLevels();
  const [coinDraft, setCoinDraft] = useState("");
  const [account, setAccount] = useState<DeltaAccountResponse | null>(null);
  const [testing, setTesting] = useState(false);
  const [saving, setSaving] = useState(false);
  const [hasStored, setHasStored] = useState(false);

  useEffect(() => {
    const c = loadCreds();
    if (c) {
      setApiKey(c.api_key);
      setLabel(c.label ?? "");
      setRegion(c.region);
      setHasStored(true);
      // Fire a test using stored creds; don't populate secret field.
      (async () => {
        setTesting(true);
        try {
          setAccount(await fetchDeltaAccount(c));
        } finally {
          setTesting(false);
        }
      })();
    }
  }, []);

  async function testCurrent() {
    if (!apiKey || !apiSecret) {
      const stored = loadCreds();
      if (!stored) {
        toast.error("Enter API key and secret first");
        return;
      }
      setTesting(true);
      try {
        setAccount(await fetchDeltaAccount(stored));
      } finally {
        setTesting(false);
      }
      return;
    }
    setTesting(true);
    try {
      const resp = await fetchDeltaAccount({ api_key: apiKey, api_secret: apiSecret, region, label });
      setAccount(resp);
      if (!resp.connected) toast.error("Delta rejected credentials", { description: resp.hint ?? resp.error });
    } catch (e) {
      toast.error("Network error", { description: e instanceof Error ? e.message : String(e) });
    } finally {
      setTesting(false);
    }
  }

  async function saveCredentials() {
    if (!apiKey || !apiSecret) {
      toast.error("Enter both API key and secret");
      return;
    }
    setSaving(true);
    try {
      const resp = await fetchDeltaAccount({ api_key: apiKey, api_secret: apiSecret, region, label });
      setAccount(resp);
      if (!resp.connected) {
        toast.error("Failed to link account", { description: resp.hint ?? resp.error });
        return;
      }
      saveCreds({ api_key: apiKey, api_secret: apiSecret, region, label });
      setHasStored(true);
      // Best-effort: mirror credentials to the backend so live-trading toggle
      // and server-side order routing can see them. Silent on failure —
      // localStorage remains the source of truth for the client-only proxy.
      try {
        await backendApi.saveDeltaCredentials({
          api_key: apiKey,
          api_secret: apiSecret,
          account_label: label,
        });
      } catch {
        /* backend unreachable — local link still works */
      }
      setApiSecret("");
      toast.success("Delta account linked", {
        description: resp.email ? `Signed in as ${resp.email}` : `Balance ${fmtUsd(resp.balance ?? 0)}`,
      });
    } catch (e) {
      toast.error("Failed to link account", { description: e instanceof Error ? e.message : String(e) });
    } finally {
      setSaving(false);
    }
  }

  function unlink() {
    clearCreds();
    setAccount(null);
    setApiKey("");
    setApiSecret("");
    setHasStored(false);
    toast.success("Delta credentials removed from this browser");
  }

  function resetForm() {
    const c = loadCreds();
    setApiKey(c?.api_key ?? "");
    setApiSecret("");
    setLabel(c?.label ?? "");
    setRegion(c?.region ?? "india");
    toast.success("Form reset", {
      description: c ? "Reverted to saved credentials" : "Cleared all fields",
    });
  }





  function saveRisk() {
    toast.success("Risk profile saved", {
      description: `${usePct ? `${pct}% of equity` : fmtUsd(fixed)} · ${leverage}x · max ${maxRisk}%`,
    });
  }

  return (
    <div className="mx-auto grid max-w-5xl gap-6 lg:grid-cols-5">
      {/* Delta connection */}
      <div className="lg:col-span-3">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <KeyRound className="h-5 w-5" />
            </div>
            <div className="flex-1">
              <h2 className="font-display text-lg font-bold">Delta Exchange API</h2>
              <p className="text-xs text-muted-foreground">
                Stored in this browser only. Signed server-side per request — never sent to Delta from your browser.
              </p>
            </div>
            <AccountStatus account={account} onRefresh={testCurrent} refreshing={testing} />
          </div>
          <Separator className="my-5" />
          <div className="grid gap-4">
            <div className="grid gap-2">
              <Label>Region</Label>
              <div className="grid grid-cols-2 gap-2">
                <button
                  type="button"
                  onClick={() => setRegion("india")}
                  className={`rounded-md border px-3 py-2 text-sm ${region === "india" ? "border-primary bg-primary/10 text-primary" : "border-border bg-background/40"}`}
                >
                  Delta India
                  <div className="text-[10px] text-muted-foreground">api.india.delta.exchange</div>
                </button>
                <button
                  type="button"
                  onClick={() => setRegion("global")}
                  className={`rounded-md border px-3 py-2 text-sm ${region === "global" ? "border-primary bg-primary/10 text-primary" : "border-border bg-background/40"}`}
                >
                  Delta Global
                  <div className="text-[10px] text-muted-foreground">api.delta.exchange</div>
                </button>
              </div>
            </div>
            <IpBadge />

            <div className="grid gap-2">
              <Label htmlFor="apiLabel">Account label (optional)</Label>
              <Input
                id="apiLabel"
                placeholder="Main · India · Trading"
                value={label}
                onChange={(e) => setLabel(e.target.value)}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="apiKey">API Key</Label>
              <Input id="apiKey" placeholder="delta_pk_…" value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="apiSecret">
                API Secret {hasStored && <span className="text-muted-foreground">(re-enter to update)</span>}
              </Label>
              <Input
                id="apiSecret"
                type="password"
                placeholder={hasStored ? "•••••••• (saved)" : "••••••••••••"}
                value={apiSecret}
                onChange={(e) => setApiSecret(e.target.value)}
              />
            </div>
            {account && !account.connected && (account.error || account.hint) && (
              <div className="rounded-lg border border-bear/40 bg-bear/10 p-3 text-xs text-bear">
                <strong>Delta rejected the request:</strong> {account.error}
                {account.hint && <div className="mt-1 text-muted-foreground">{account.hint}</div>}
              </div>
            )}
            <div className="rounded-lg border border-warning/30 bg-warning/5 p-3 text-xs text-warning">
              <ShieldCheck className="mr-1 inline h-3.5 w-3.5" />
              Grant only <span className="font-bold">Trade + Read</span> permissions. Never enable Withdraw. If Delta requires IP whitelisting, allow the origin server IP.
            </div>
            <div className="flex flex-wrap gap-2">
              <Button onClick={saveCredentials} disabled={saving} className="gap-2">
                <Link2 className="h-4 w-4" />
                {saving ? "Linking…" : account?.connected ? "Update Credentials" : "Link Account"}
              </Button>
              <Button variant="outline" onClick={testCurrent} disabled={testing} className="gap-2">
                <RefreshCw className={`h-4 w-4 ${testing ? "animate-spin" : ""}`} />
                Test connection
              </Button>
              <Button variant="outline" onClick={resetForm} className="gap-2">
                <RotateCcw className="h-4 w-4" />
                Reset
              </Button>
              {hasStored && (
                <Button variant="ghost" onClick={unlink} className="gap-2 text-bear hover:text-bear">
                  <Trash2 className="h-4 w-4" />
                  Unlink
                </Button>
              )}
            </div>
          </div>
          <Separator className="my-5" />
          <LiveTradingToggle hasCredentials={!!account?.connected || hasStored} />
        </Card>
      </div>


      {/* Sizing */}
      <div className="lg:col-span-2">
        <Card className="glass p-6">
          <h2 className="font-display text-lg font-bold">Trade Sizing</h2>
          <p className="text-xs text-muted-foreground">Applies to every auto-generated entry.</p>
          <Separator className="my-4" />
          <div className="flex items-center justify-between rounded-lg border border-border bg-background/40 p-3">
            <div className="flex items-center gap-2 text-sm">
              {usePct ? <Percent className="h-4 w-4 text-primary" /> : <DollarSign className="h-4 w-4 text-primary" />}
              <span className="font-medium">{usePct ? "Percentage of equity" : "Fixed USD amount"}</span>
            </div>
            <Switch checked={usePct} onCheckedChange={setUsePct} />
          </div>
          <div className="mt-4 grid gap-3">
            {usePct ? (
              <div className="grid gap-2">
                <Label>Percent of balance per trade</Label>
                <div className="grid grid-cols-[minmax(0,1fr)_auto] gap-2">
                  <Input type="number" min={0.1} max={50} step={0.1} value={pct} onChange={(e) => setPct(+e.target.value)} className="num" />
                  <div className="grid place-items-center rounded-md border border-border px-3 text-sm text-muted-foreground">%</div>
                </div>
              </div>
            ) : (
              <div className="grid gap-2">
                <Label>Fixed amount</Label>
                <div className="grid grid-cols-[auto_minmax(0,1fr)] gap-2">
                  <div className="grid place-items-center rounded-md border border-border px-3 text-sm text-muted-foreground">$</div>
                  <Input type="number" min={10} step={10} value={fixed} onChange={(e) => setFixed(+e.target.value)} className="num" />
                </div>
              </div>
            )}
            <div className="grid gap-2">
              <Label>Default leverage</Label>
              <Input type="number" min={1} max={100} value={leverage} onChange={(e) => setLeverage(+e.target.value)} className="num" />
            </div>
            <div className="grid gap-2">
              <Label>Max risk / trade (%)</Label>
              <Input type="number" min={0.1} max={10} step={0.1} value={maxRisk} onChange={(e) => setMaxRisk(+e.target.value)} className="num" />
            </div>
          </div>
        </Card>
      </div>

      {/* Approval mode */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <ShieldCheck className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Trade Execution Mode</h2>
              <p className="text-xs text-muted-foreground">Choose whether new signals require your approval before hitting Delta Exchange.</p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-3 sm:grid-cols-2">
            <button
              type="button"
              onClick={() => setApprovalMode("manual")}
              className={`flex items-start gap-3 rounded-lg border p-4 text-left transition ${approvalMode === "manual" ? "border-primary bg-primary/10" : "border-border bg-background/40 hover:border-primary/40"}`}
            >
              <CheckCircle2 className={`mt-0.5 h-5 w-5 shrink-0 ${approvalMode === "manual" ? "text-primary" : "text-muted-foreground"}`} />
              <div className="min-w-0">
                <div className="font-display text-sm font-bold">Ask for approval</div>
                <p className="mt-1 text-xs text-muted-foreground">Every signal shows up as a pending trade. You approve or reject before it's placed.</p>
              </div>
            </button>
            <button
              type="button"
              onClick={() => setApprovalMode("auto")}
              className={`flex items-start gap-3 rounded-lg border p-4 text-left transition ${approvalMode === "auto" ? "border-primary bg-primary/10" : "border-border bg-background/40 hover:border-primary/40"}`}
            >
              <Zap className={`mt-0.5 h-5 w-5 shrink-0 ${approvalMode === "auto" ? "text-primary" : "text-muted-foreground"}`} />
              <div className="min-w-0">
                <div className="font-display text-sm font-bold">Auto approve</div>
                <p className="mt-1 text-xs text-muted-foreground">Signals are executed automatically using your sizing and leverage rules above.</p>
              </div>
            </button>
          </div>
          <div className="mt-4 rounded-lg border border-border bg-background/40 p-3">
            <div className="flex items-center justify-between gap-3">
              <div className="min-w-0">
                <Label htmlFor="tradeThreshold" className="text-sm font-semibold">Trade confidence threshold</Label>
                <p className="text-xs text-muted-foreground">Signals at or above this confidence show as TRADE; below they surface as WAIT.</p>
              </div>
              <span className="num rounded-md border border-primary/40 bg-primary/10 px-2 py-1 text-sm font-bold text-primary">
                {Math.round(tradeThreshold * 100)}%
              </span>
            </div>
            <Input
              id="tradeThreshold"
              type="range"
              min={0.3}
              max={0.95}
              step={0.05}
              value={tradeThreshold}
              onChange={(e) => setTradeThreshold(Number(e.target.value))}
              className="mt-3"
            />
          </div>

          {approvalMode === "auto" && (
            <div className="mt-4 rounded-lg border border-warning/30 bg-warning/5 p-3 text-xs text-warning">
              <ShieldCheck className="mr-1 inline h-3.5 w-3.5" />
              Auto-approval is active. Trades will be placed on Delta without confirmation — make sure your sizing and max-risk limits are correct.
            </div>
          )}

          {approvalMode === "auto" && (
            <>
              <Separator className="my-5" />
              <div>
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <h3 className="font-display text-sm font-bold">Auto-exit rules</h3>
                    <p className="text-xs text-muted-foreground">Close trades early when the signal reverses, and trail the stop as price runs in your favour.</p>
                  </div>
                </div>

                <div className="mt-4 space-y-4">
                  {/* Reverse exit */}
                  <div className="rounded-lg border border-border bg-background/40 p-3">
                    <div className="flex items-center justify-between gap-3">
                      <div className="min-w-0">
                        <div className="text-sm font-semibold">Close on trend reversal</div>
                        <p className="text-xs text-muted-foreground">Exit immediately if a fresh opposite-side signal appears above the confidence threshold — don't wait for SL.</p>
                      </div>
                      <Switch checked={autoExit.reverseExit} onCheckedChange={(v) => updateAutoExit({ reverseExit: v })} />
                    </div>
                    {autoExit.reverseExit && (
                      <div className="mt-3 grid gap-2">
                        <Label htmlFor="revConf" className="text-xs">Min opposing confidence · {(autoExit.reverseMinConfidence * 100).toFixed(0)}%</Label>
                        <Input
                          id="revConf"
                          type="range"
                          min={0.4}
                          max={0.95}
                          step={0.05}
                          value={autoExit.reverseMinConfidence}
                          onChange={(e) => updateAutoExit({ reverseMinConfidence: Number(e.target.value) })}
                        />
                      </div>
                    )}
                  </div>

                  {/* Trailing SL */}
                  <div className="rounded-lg border border-border bg-background/40 p-3">
                    <div className="flex items-center justify-between gap-3">
                      <div className="min-w-0">
                        <div className="text-sm font-semibold">Trailing stop loss</div>
                        <p className="text-xs text-muted-foreground">Ratchet SL behind the best price seen — only tightens, never loosens.</p>
                      </div>
                      <Switch checked={autoExit.trailingSl} onCheckedChange={(v) => updateAutoExit({ trailingSl: v })} />
                    </div>
                    {autoExit.trailingSl && (
                      <div className="mt-3 grid gap-3 sm:grid-cols-2">
                        <div className="grid gap-2">
                          <Label htmlFor="trailDist" className="text-xs">Trail distance (% of entry)</Label>
                          <Input
                            id="trailDist"
                            type="number"
                            min={0.1}
                            step={0.1}
                            value={autoExit.trailingDistancePct}
                            onChange={(e) => updateAutoExit({ trailingDistancePct: Math.max(0.1, Number(e.target.value) || 0) })}
                          />
                        </div>
                        <div className="grid gap-2">
                          <Label htmlFor="trailArm" className="text-xs">Arm after profit ≥ (%)</Label>
                          <Input
                            id="trailArm"
                            type="number"
                            min={0}
                            step={0.1}
                            value={autoExit.trailingActivatePct}
                            onChange={(e) => updateAutoExit({ trailingActivatePct: Math.max(0, Number(e.target.value) || 0) })}
                          />
                        </div>
                      </div>
                    )}
                  </div>
                </div>
              </div>
            </>
          )}
        </Card>
      </div>

      {/* Trend Matrix preferences */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <LayoutGrid className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Trend Matrix</h2>
              <p className="text-xs text-muted-foreground">
                Choose how many trending Delta perpetuals appear on the dashboard, and manage pinned favourites.
              </p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-5 md:grid-cols-2">
            <div className="grid gap-2">
              <Label htmlFor="coinCount">Coins to display</Label>
              <div className="grid grid-cols-[minmax(0,1fr)_auto] gap-2">
                <Input
                  id="coinCount"
                  type="number"
                  min={MIN_COIN_COUNT}
                  max={MAX_COIN_COUNT}
                  value={coinCount}
                  onChange={(e) => setCoinCount(+e.target.value || MIN_COIN_COUNT)}
                  className="num"
                />
                <div className="grid place-items-center rounded-md border border-border px-3 text-sm text-muted-foreground">
                  {MIN_COIN_COUNT}–{MAX_COIN_COUNT}
                </div>
              </div>
              <p className="text-[11px] text-muted-foreground">
                Ranked by 24h turnover from Delta. Favourites always pin to the top and count toward this total.
              </p>
            </div>
            <div className="grid gap-2">
              <Label>Pinned favourites</Label>
              {favorites.length === 0 ? (
                <div className="rounded-md border border-dashed border-border p-3 text-xs text-muted-foreground">
                  <Star className="mr-1 inline h-3.5 w-3.5" />
                  Tap the star on any coin card to pin it to the top of the matrix.
                </div>
              ) : (
                <div className="flex flex-wrap gap-1.5">
                  {favorites.map((s) => (
                    <button
                      key={s}
                      type="button"
                      onClick={() => removeFavorite(s)}
                      className="group inline-flex items-center gap-1 rounded-md border border-primary/40 bg-primary/10 px-2 py-1 text-xs text-primary hover:border-bear/50 hover:bg-bear/10 hover:text-bear"
                      aria-label={`Unpin ${s}`}
                    >
                      <Star className="h-3 w-3 fill-current" />
                      {s}
                      <XIcon className="h-3 w-3 opacity-60 group-hover:opacity-100" />
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>
        </Card>
      </div>

      {/* Signals list preferences */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <ListOrdered className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Signals list</h2>
              <p className="text-xs text-muted-foreground">
                Choose how many rows to show per page on the Signals history table.
              </p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-2 md:max-w-sm">
            <Label>Rows per page</Label>
            <div className="flex flex-wrap gap-2">
              {SIGNALS_PAGE_SIZE_OPTIONS.map((n) => (
                <button
                  key={n}
                  type="button"
                  onClick={() => setSignalsPageSize(n as SignalsPageSize)}
                  className={`rounded-md border px-3 py-1.5 text-sm ${
                    signalsPageSize === n
                      ? "border-primary bg-primary/10 text-primary"
                      : "border-border bg-background/40 text-muted-foreground hover:text-foreground"
                  }`}
                  aria-pressed={signalsPageSize === n}
                >
                  {n} / page
                </button>
              ))}
            </div>
            <p className="text-[11px] text-muted-foreground">
              Default is 10. Applies immediately to the Signals page for this browser.
            </p>
          </div>
        </Card>
      </div>

      {/* Trade limits */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <Gauge className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Trade limits</h2>
              <p className="text-xs text-muted-foreground">
                Cap the number of open positions and/or new trades per day.
                Leave a field <strong>empty</strong> for no restriction.
              </p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-4 md:grid-cols-2">
            <div className="grid gap-1.5">
              <Label htmlFor="max-active">Max concurrent open positions</Label>
              <Input
                id="max-active"
                inputMode="numeric"
                placeholder="Unlimited"
                value={tradeLimits.activeRaw}
                onChange={(e) => tradeLimits.setActive(e.target.value.replace(/[^0-9]/g, ""))}
              />
              <p className="text-[11px] text-muted-foreground">
                {tradeLimits.limits.maxActive == null
                  ? "No cap — approve as many signals as you want."
                  : `Approvals are blocked once ${tradeLimits.limits.maxActive} position${tradeLimits.limits.maxActive === 1 ? " is" : "s are"} open.`}
              </p>
            </div>
            <div className="grid gap-1.5">
              <Label htmlFor="max-daily">Max trades per day</Label>
              <Input
                id="max-daily"
                inputMode="numeric"
                placeholder="Unlimited"
                value={tradeLimits.dailyRaw}
                onChange={(e) => tradeLimits.setDaily(e.target.value.replace(/[^0-9]/g, ""))}
              />
              <p className="text-[11px] text-muted-foreground">
                Today: <strong>{countTradesToday()}</strong> initiated
                {tradeLimits.limits.maxPerDay != null && ` / ${tradeLimits.limits.maxPerDay}`}
                . Resets at midnight local time.
              </p>
            </div>
          </div>
        </Card>
      </div>

      {/* Tradable coins whitelist */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <Star className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Tradable coins</h2>
              <p className="text-xs text-muted-foreground">
                Restrict signal generation and approvals to a specific list of symbols.
                Leave the list <strong>empty</strong> to allow all coins.
              </p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-3">
            <div className="flex flex-wrap gap-2">
              <Input
                placeholder="e.g. BTCUSD"
                value={coinDraft}
                onChange={(e) => setCoinDraft(e.target.value.toUpperCase())}
                onKeyDown={(e) => {
                  if (e.key === "Enter" && coinDraft.trim()) {
                    e.preventDefault();
                    allowedCoins.add(coinDraft);
                    setCoinDraft("");
                  }
                }}
                className="max-w-[220px] uppercase"
              />
              <Button
                type="button"
                variant="outline"
                onClick={() => {
                  if (!coinDraft.trim()) return;
                  allowedCoins.add(coinDraft);
                  setCoinDraft("");
                }}
              >
                Add
              </Button>
              {allowedCoins.coins.length > 0 && (
                <Button type="button" variant="ghost" onClick={allowedCoins.clear} className="text-muted-foreground">
                  Clear all
                </Button>
              )}
            </div>
            <div className="flex flex-wrap gap-2">
              {allowedCoins.coins.length === 0 ? (
                <p className="text-[11px] text-muted-foreground">
                  All coins are currently tradable. Add symbols to restrict.
                </p>
              ) : (
                allowedCoins.coins.map((c) => (
                  <Badge
                    key={c}
                    variant="outline"
                    className="gap-1 border-primary/40 bg-primary/10 text-primary"
                  >
                    {c}
                    <button
                      type="button"
                      onClick={() => allowedCoins.remove(c)}
                      className="ml-1 rounded-sm hover:bg-primary/20"
                      aria-label={`Remove ${c}`}
                    >
                      <XIcon className="h-3 w-3" />
                    </button>
                  </Badge>
                ))
              )}
            </div>
            <p className="text-[11px] text-muted-foreground">
              Applies to the browser strategy engine and Pending Signal approvals.
              Approvals for excluded coins are blocked with a toast.
            </p>
          </div>
        </Card>
      </div>

      {/* Coin risk tiers */}
      <div className="lg:col-span-5">
        <Card className="glass p-6">
          <div className="flex items-center gap-3">
            <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-primary/15 text-primary">
              <Star className="h-5 w-5" />
            </div>
            <div>
              <h2 className="font-display text-lg font-bold">Risk tiers</h2>
              <p className="text-xs text-muted-foreground">
                Every coin is flagged <strong>Safe</strong>, <strong>Moderate</strong> or
                {" "}<strong>Vulnerable</strong> based on liquidity and market depth. Disable a tier to
                hide those coins from Pending Signals and block their approvals.
              </p>
            </div>
          </div>
          <Separator className="my-5" />
          <div className="grid gap-2 sm:grid-cols-3">
            {COIN_RISK_LEVELS.map((lvl) => {
              const meta = RISK_META[lvl];
              const on = riskLevels.levels.includes(lvl);
              return (
                <button
                  key={lvl}
                  type="button"
                  onClick={() => riskLevels.toggle(lvl)}
                  aria-pressed={on}
                  className={`group flex items-start gap-3 rounded-lg border p-3 text-left transition ${
                    on
                      ? `${meta.tone} ring-1 ring-inset ring-current/20`
                      : "border-border/60 bg-background/30 text-muted-foreground hover:border-border"
                  }`}
                >
                  <span className={`mt-1 h-2.5 w-2.5 shrink-0 rounded-full ${meta.dot}`} aria-hidden />
                  <span className="min-w-0 flex-1">
                    <span className="flex items-center justify-between gap-2">
                      <span className="font-display text-sm font-bold uppercase tracking-widest">
                        {meta.label}
                      </span>
                      <span className={`text-[10px] uppercase tracking-widest ${on ? "" : "opacity-60"}`}>
                        {on ? "Shown" : "Hidden"}
                      </span>
                    </span>
                    <span className="mt-1 block text-[11px] leading-snug opacity-80">
                      {meta.description}
                    </span>
                  </span>
                </button>
              );
            })}
          </div>
          <p className="mt-3 text-[11px] text-muted-foreground">
            At least one tier is always kept on. Disabling all resets to showing every tier.
          </p>
        </Card>
      </div>


      <div className="lg:col-span-5">
        <AlertRulesCard />
      </div>

      <div className="lg:col-span-5">
        <Button onClick={saveRisk} className="w-full sm:w-auto">Save Risk Profile</Button>
      </div>
    </div>
  );
}

function AccountStatus({
  account,
  onRefresh,
  refreshing,
}: {
  account: DeltaAccountResponse | null;
  onRefresh: () => void;
  refreshing: boolean;
}) {
  if (!account || !account.connected) {
    return (
      <Badge variant="outline" className="border-bear/40 text-bear">
        Not linked
      </Badge>
    );
  }
  return (
    <div className="flex items-center gap-2 text-right text-xs">
      <div>
        <Badge variant="outline" className="border-bull/40 text-bull">
          Live · {account.email ?? account.account_id}
        </Badge>
        <div className="mt-1 text-muted-foreground">
          {account.balance != null ? `${fmtUsd(account.balance)} ${account.currency ?? ""}` : ""}
          {account.permissions?.length ? ` · ${account.permissions.join(", ")}` : ""}
        </div>
      </div>
      <button
        type="button"
        onClick={onRefresh}
        className="rounded-md border border-border p-1.5 text-muted-foreground hover:text-foreground"
        title="Refresh"
      >
        <RefreshCw className={`h-3.5 w-3.5 ${refreshing ? "animate-spin" : ""}`} />
      </button>
    </div>
  );
}

function LiveTradingToggle({ hasCredentials }: { hasCredentials: boolean }) {
  const [enabled, setEnabled] = useState(false);
  const [envEnabled, setEnvEnabled] = useState(false);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [unreachable, setUnreachable] = useState(false);

  useEffect(() => {
    let alive = true;
    backendApi
      .getLiveTrading()
      .then((r) => {
        if (!alive) return;
        setEnabled(!!r.live_trading_enabled);
        setEnvEnabled(!!r.env_enabled);
        setUnreachable(false);
      })
      .catch(() => alive && setUnreachable(true))
      .finally(() => alive && setLoading(false));
    return () => { alive = false; };
  }, []);

  async function toggle(next: boolean) {
    // Only require linked credentials when *enabling* live routing.
    // Switching back to paper must always work.
    if (next && !hasCredentials) {
      toast.error("Link your Delta API credentials first");
      return;
    }
    setSaving(true);
    try {
      const r = await backendApi.setLiveTrading(next);
      setEnabled(!!r.live_trading_enabled);
      toast.success(next ? "Live routing enabled" : "Switched to paper mode", {
        description: next
          ? "New trades will be routed to Delta Exchange."
          : "New trades will simulate against live prices without hitting Delta.",
      });
    } catch (e) {
      toast.error("Failed to update", { description: (e as Error).message });
    } finally {
      setSaving(false);
    }
  }

  return (
    <div>
      <div className="flex items-start gap-3">
        <div className={`grid h-10 w-10 shrink-0 place-items-center rounded-xl ${enabled ? "bg-bull/15 text-bull" : "bg-muted/40 text-muted-foreground"}`}>
          <ZapIcon className="h-5 w-5" />
        </div>
        <div className="flex-1">
          <div className="flex items-center gap-2">
            <h3 className="font-display text-base font-bold">Live Order Routing</h3>
            <Badge
              variant="outline"
              className={enabled ? "border-bull/50 bg-bull/10 text-bull" : "border-border text-muted-foreground"}
            >
              {enabled ? "LIVE" : "PAPER"}
            </Badge>
          </div>
          <p className="mt-0.5 text-xs text-muted-foreground">
            {enabled
              ? "Approved signals and manual trades are placed on Delta Exchange with real capital."
              : "Trades are simulated against live prices — nothing is sent to Delta."}
          </p>
        </div>
        <Switch
          checked={enabled}
          onCheckedChange={toggle}
          disabled={loading || saving || unreachable || (!hasCredentials && !enabled)}
          aria-label="Toggle live order routing"
        />
      </div>
      {!envEnabled && !unreachable && !loading && (
        <div className="mt-3 rounded-lg border border-warning/30 bg-warning/5 p-3 text-xs text-warning">
          <ShieldCheck className="mr-1 inline h-3.5 w-3.5" />
          Server flag <code className="font-mono">DELTA_LIVE_ORDERS=1</code> is off. Trades will remain in paper mode until an operator enables it.
        </div>
      )}
      {!hasCredentials && (
        <div className="mt-3 rounded-lg border border-border bg-background/40 p-3 text-xs text-muted-foreground">
          Link your Delta API credentials above before enabling live routing.
        </div>
      )}
      {unreachable && (
        <div className="mt-3 rounded-lg border border-border bg-background/40 p-3 text-xs text-muted-foreground">
          Backend unreachable — live routing status unavailable.
        </div>
      )}
    </div>
  );
}
