// Settings UI for spread/latency alert rules. Configures a global default
// plus optional per-symbol overrides, with live preview of which severity
// tier each threshold would fire.

import { useEffect, useState } from "react";
import { toast } from "sonner";
import { AlertTriangle, Bell, BellOff, Plus, RotateCcw, Trash2 } from "lucide-react";
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 {
  useAlertRules,
  DEFAULT_THRESHOLDS,
  type AlertThresholds,
} from "@/lib/alert-rules";
import {
  ensurePushPermission,
  firePushNotification,
  getPushPermission,
  pushSupported,
  readPushEnabled,
  writePushEnabled,
  type PushPermission,
} from "@/lib/push-notifications";

function NumField({
  id,
  label,
  suffix,
  value,
  onChange,
  min = 0,
  step = 1,
  disabled,
}: {
  id: string;
  label: string;
  suffix?: string;
  value: number;
  onChange: (n: number) => void;
  min?: number;
  step?: number;
  disabled?: boolean;
}) {
  return (
    <div className="space-y-1.5">
      <Label htmlFor={id} className="text-xs">
        {label}
      </Label>
      <div className="relative">
        <Input
          id={id}
          type="number"
          inputMode="decimal"
          value={Number.isFinite(value) ? value : 0}
          min={min}
          step={step}
          disabled={disabled}
          onChange={(e) => {
            const n = Number(e.target.value);
            if (Number.isFinite(n)) onChange(n);
          }}
          className="num pr-12"
        />
        {suffix && (
          <span className="pointer-events-none absolute inset-y-0 right-2 flex items-center text-[10px] uppercase tracking-wider text-muted-foreground">
            {suffix}
          </span>
        )}
      </div>
    </div>
  );
}

function ThresholdBlock({
  values,
  onChange,
  compact,
}: {
  values: AlertThresholds;
  onChange: (patch: Partial<AlertThresholds>) => void;
  compact?: boolean;
}) {
  return (
    <div className={compact ? "grid gap-3 md:grid-cols-2" : "grid gap-4 md:grid-cols-2"}>
      <div className="rounded-lg border border-border/60 bg-secondary/20 p-3">
        <div className="flex items-center justify-between">
          <div>
            <div className="text-[11px] uppercase tracking-wider text-muted-foreground">Spread</div>
            <div className="text-sm font-semibold">Bid/ask spread (bps)</div>
          </div>
          <Switch
            checked={values.spreadEnabled}
            onCheckedChange={(v) => onChange({ spreadEnabled: v })}
            aria-label="Enable spread alert"
          />
        </div>
        <div className="mt-3 grid grid-cols-2 gap-2">
          <NumField
            id="spread-warn"
            label="Warn ≥"
            suffix="bps"
            value={values.spreadWarnBps}
            onChange={(n) => onChange({ spreadWarnBps: Math.max(0, n) })}
            disabled={!values.spreadEnabled}
          />
          <NumField
            id="spread-crit"
            label="Critical ≥"
            suffix="bps"
            value={values.spreadCritBps}
            onChange={(n) => onChange({ spreadCritBps: Math.max(0, n) })}
            disabled={!values.spreadEnabled}
          />
        </div>
      </div>

      <div className="rounded-lg border border-border/60 bg-secondary/20 p-3">
        <div className="flex items-center justify-between">
          <div>
            <div className="text-[11px] uppercase tracking-wider text-muted-foreground">Latency</div>
            <div className="text-sm font-semibold">Tick freshness</div>
          </div>
          <Switch
            checked={values.latencyEnabled}
            onCheckedChange={(v) => onChange({ latencyEnabled: v })}
            aria-label="Enable latency alert"
          />
        </div>
        <div className="mt-3 grid grid-cols-2 gap-2">
          <NumField
            id="lat-warn"
            label="Warn ≥"
            suffix="ms"
            value={values.latencyWarnMs}
            onChange={(n) => onChange({ latencyWarnMs: Math.max(100, n) })}
            step={100}
            min={100}
            disabled={!values.latencyEnabled}
          />
          <NumField
            id="lat-crit"
            label="Critical ≥"
            suffix="ms"
            value={values.latencyCritMs}
            onChange={(n) => onChange({ latencyCritMs: Math.max(200, n) })}
            step={100}
            min={200}
            disabled={!values.latencyEnabled}
          />
        </div>
      </div>
    </div>
  );
}

export function AlertRulesCard() {
  const { rules, update, setGlobal, setOverride, reset } = useAlertRules();
  const [newSymbol, setNewSymbol] = useState("");
  const [pushEnabled, setPushEnabled] = useState(() => readPushEnabled());
  const [pushPerm, setPushPerm] = useState<PushPermission>(() => getPushPermission());

  useEffect(() => {
    const onChange = () => {
      setPushEnabled(readPushEnabled());
      setPushPerm(getPushPermission());
    };
    window.addEventListener("delta:push-enabled-changed", onChange);
    return () => window.removeEventListener("delta:push-enabled-changed", onChange);
  }, []);

  async function togglePush(next: boolean) {
    if (!next) {
      writePushEnabled(false);
      setPushEnabled(false);
      toast.message("Background push notifications disabled");
      return;
    }
    if (!pushSupported()) {
      toast.error("This browser doesn't support notifications");
      return;
    }
    const perm = await ensurePushPermission();
    setPushPerm(perm);
    if (perm !== "granted") {
      toast.error(
        perm === "denied"
          ? "Notifications are blocked — enable them in your browser site settings."
          : "Notification permission not granted.",
      );
      return;
    }
    writePushEnabled(true);
    setPushEnabled(true);
    toast.success("Background alerts enabled");
    // Fire a confirmation notification so the user sees exactly what to expect.
    firePushNotification({
      title: "Delta Terminal · Alerts armed",
      body: "You'll be notified when spread or tick latency crosses your thresholds.",
      severity: "warn",
      tag: "delta:test",
    });
  }


  const overrideSymbols = Object.keys(rules.overrides).sort();

  return (
    <Card className="glass p-6">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <div className="flex items-center gap-2">
            {rules.enabled ? (
              <Bell className="h-4 w-4 text-primary" />
            ) : (
              <BellOff className="h-4 w-4 text-muted-foreground" />
            )}
            <h3 className="font-display text-base font-semibold">Alert Rules</h3>
            <Badge variant="outline" className="border-border/60 text-[10px]">
              Spread · Latency
            </Badge>
          </div>
          <p className="mt-1 text-xs text-muted-foreground">
            Toast notifications when bid/ask spread or tick staleness cross warning or critical levels. Per-symbol
            overrides win over the global default and cause the terminal to keep those symbols subscribed on every page.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Label htmlFor="alerts-enabled" className="text-xs text-muted-foreground">
            {rules.enabled ? "On" : "Off"}
          </Label>
          <Switch
            id="alerts-enabled"
            checked={rules.enabled}
            onCheckedChange={(v) => update({ enabled: v })}
            aria-label="Master alert switch"
          />
        </div>
      </div>

      <div className="mt-3 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border/60 bg-secondary/20 p-3">
        <div className="min-w-0">
          <div className="text-[11px] uppercase tracking-wider text-muted-foreground">Background delivery</div>
          <div className="text-sm font-semibold">Browser push notifications</div>
          <p className="mt-0.5 text-[11px] text-muted-foreground">
            Get an OS-level notification when this browser tab is hidden or backgrounded. Toasts always fire on the
            active tab; push is added on top for critical breaches.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Badge
            variant="outline"
            className={
              pushPerm === "granted"
                ? "border-primary/40 text-[10px] text-primary"
                : pushPerm === "denied"
                ? "border-destructive/40 text-[10px] text-destructive"
                : "border-border/60 text-[10px] text-muted-foreground"
            }
          >
            {pushPerm === "unsupported" ? "Unsupported" : pushPerm}
          </Badge>
          <Switch
            id="alerts-push"
            checked={pushEnabled && pushPerm === "granted"}
            onCheckedChange={togglePush}
            disabled={pushPerm === "unsupported"}
            aria-label="Enable background push notifications"
          />
        </div>
      </div>

      <Separator className="my-4" />


      <div className="mb-2 flex items-center justify-between">
        <div className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
          Global defaults
        </div>
        <div className="flex items-center gap-3">
          <div className="flex items-center gap-2 text-[11px] text-muted-foreground">
            <span>Cooldown</span>
            <Input
              type="number"
              min={5}
              step={5}
              value={Math.round(rules.cooldownMs / 1000)}
              onChange={(e) => {
                const s = Math.max(5, Number(e.target.value) || 60);
                update({ cooldownMs: s * 1000 });
              }}
              className="num h-7 w-16"
              aria-label="Cooldown seconds"
            />
            <span>s</span>
          </div>
        </div>
      </div>

      <ThresholdBlock values={rules.global} onChange={(p) => setGlobal(p)} />

      <Separator className="my-4" />

      <div className="mb-3 flex items-center justify-between gap-3">
        <div>
          <div className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
            Per-symbol overrides
          </div>
          <div className="text-[11px] text-muted-foreground">
            {overrideSymbols.length
              ? `${overrideSymbols.length} configured`
              : "None — the global rule applies to every symbol."}
          </div>
        </div>
        <form
          className="flex items-center gap-2"
          onSubmit={(e) => {
            e.preventDefault();
            const raw = newSymbol.trim().toUpperCase();
            if (!raw) return;
            if (rules.overrides[raw]) {
              toast.info(`${raw} already has an override`);
              return;
            }
            setOverride(raw, { ...DEFAULT_THRESHOLDS, ...rules.global });
            setNewSymbol("");
            toast.success(`Added override for ${raw}`);
          }}
        >
          <Input
            value={newSymbol}
            onChange={(e) => setNewSymbol(e.target.value)}
            placeholder="e.g. BTCUSD"
            aria-label="Symbol"
            className="h-9 w-40 uppercase"
          />
          <Button type="submit" size="sm" variant="secondary" className="h-9 gap-1">
            <Plus className="h-3.5 w-3.5" /> Add
          </Button>
        </form>
      </div>

      <div className="space-y-3">
        {overrideSymbols.map((sym) => (
          <div key={sym} className="rounded-lg border border-border/60 bg-background/40 p-3">
            <div className="mb-2 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <AlertTriangle className="h-3.5 w-3.5 text-warning" />
                <span className="font-display text-sm font-bold tracking-wide">{sym}</span>
                <Badge variant="outline" className="border-primary/40 text-[10px] text-primary">
                  Override
                </Badge>
              </div>
              <Button
                variant="ghost"
                size="sm"
                className="h-7 gap-1 text-bear hover:text-bear"
                onClick={() => {
                  setOverride(sym, null);
                  toast.message(`Removed override for ${sym}`);
                }}
              >
                <Trash2 className="h-3.5 w-3.5" />
                Remove
              </Button>
            </div>
            <ThresholdBlock
              compact
              values={rules.overrides[sym]}
              onChange={(p) => setOverride(sym, p)}
            />
          </div>
        ))}
      </div>

      <Separator className="my-4" />

      <div className="flex items-center justify-between gap-2">
        <div className="text-[11px] text-muted-foreground">
          Alerts fire once per severity and re-arm after the cooldown, or immediately on warn → critical escalation.
        </div>
        <Button
          variant="outline"
          size="sm"
          onClick={() => {
            reset();
            toast.success("Alert rules reset to defaults");
          }}
          className="gap-1"
        >
          <RotateCcw className="h-3.5 w-3.5" />
          Reset defaults
        </Button>
      </div>
    </Card>
  );
}
