// Enable/disable algos + add a new custom algo by name. The dialog calls
// /api/algo/generate to translate the user's plain-English idea into a
// declarative rule spec via Lovable AI, then stores it locally.

import { useState } from "react";
import { toast } from "sonner";
import { Plus, Sparkles, Trash2, Wand2 } from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { useAlgoRegistry } from "@/lib/algo-registry";
import { parseCustomAlgoSpec } from "@/lib/custom-algo-eval";

export function AlgoManager() {
  const { all, enabled, custom, toggle, add, remove } = useAlgoRegistry();
  const [open, setOpen] = useState(false);
  const enabledCount = all.filter((a) => enabled[a.key] !== false).length;

  return (
    <div className="flex items-center gap-1">
      <Popover>
        <PopoverTrigger asChild>
          <Button
            size="sm"
            variant="outline"
            className="h-8 gap-1 px-2 text-xs"
            aria-label="Manage algorithms"
          >
            <Sparkles className="h-3.5 w-3.5" aria-hidden />
            Algos
            <Badge variant="outline" className="ml-1 border-primary/40 text-[10px] text-primary">
              {enabledCount}/{all.length}
            </Badge>
          </Button>
        </PopoverTrigger>
        <PopoverContent align="end" className="w-[320px] p-0">
          <div className="border-b border-border/60 px-3 py-2">
            <div className="text-xs font-semibold">Active algorithms</div>
            <div className="text-[10px] text-muted-foreground">
              Only enabled algos produce pending signals.
            </div>
          </div>
          <ScrollArea className="max-h-[280px]">
            <ul className="divide-y divide-border/50">
              {all.map((a) => {
                const isCustom = a.custom;
                const on = enabled[a.key] !== false;
                return (
                  <li key={a.key} className="flex items-center justify-between gap-2 px-3 py-2">
                    <div className="min-w-0 flex-1">
                      <div className="truncate text-xs font-medium">{a.label}</div>
                      <div className="text-[10px] uppercase tracking-widest text-muted-foreground">
                        {isCustom ? "Custom · AI-generated" : "Built-in"}
                      </div>
                    </div>
                    {isCustom && (
                      <button
                        onClick={() => remove(a.key)}
                        className="rounded p-1 text-muted-foreground hover:bg-destructive/10 hover:text-destructive"
                        aria-label={`Delete ${a.label}`}
                        title="Delete custom algo"
                      >
                        <Trash2 className="h-3 w-3" aria-hidden />
                      </button>
                    )}
                    <Switch
                      checked={on}
                      onCheckedChange={(v) => toggle(a.key, v)}
                      aria-label={`Toggle ${a.label}`}
                    />
                  </li>
                );
              })}
            </ul>
          </ScrollArea>
          <div className="border-t border-border/60 p-2">
            <Button
              size="sm"
              className="h-8 w-full gap-1 text-xs"
              onClick={() => setOpen(true)}
            >
              <Plus className="h-3.5 w-3.5" aria-hidden />
              Add new algo
            </Button>
          </div>
        </PopoverContent>
      </Popover>

      <AddAlgoDialog
        open={open}
        onOpenChange={setOpen}
        onCreated={(spec) => {
          add(spec);
          toast.success(`Algo "${spec.label}" added and enabled`);
        }}
        existingCount={custom.length}
      />
    </div>
  );
}

function AddAlgoDialog({
  open,
  onOpenChange,
  onCreated,
  existingCount,
}: {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  onCreated: (spec: ReturnType<typeof parseCustomAlgoSpec>) => void;
  existingCount: number;
}) {
  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [loading, setLoading] = useState(false);
  const [preview, setPreview] = useState<ReturnType<typeof parseCustomAlgoSpec> | null>(null);

  async function generate() {
    if (!name.trim()) {
      toast.error("Give the algo a name first");
      return;
    }
    setLoading(true);
    setPreview(null);
    try {
      const r = await fetch("/api/algo/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: name.trim(), description: description.trim() }),
      });
      const j = await r.json();
      if (!r.ok) throw new Error(j?.error || `HTTP ${r.status}`);
      const spec = parseCustomAlgoSpec({ ...j.spec, label: j.spec?.label || name.trim(), description });
      setPreview(spec);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "AI generation failed");
    } finally {
      setLoading(false);
    }
  }

  function save() {
    if (!preview) return;
    onCreated(preview);
    setName("");
    setDescription("");
    setPreview(null);
    onOpenChange(false);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Wand2 className="h-4 w-4 text-primary" aria-hidden />
            Add a new algorithm
          </DialogTitle>
          <DialogDescription>
            Describe the setup in plain English. Lovable AI drafts a rule spec you can review before saving.
            {existingCount > 0 && ` You already have ${existingCount} custom algo${existingCount === 1 ? "" : "s"}.`}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3">
          <div className="space-y-1">
            <Label htmlFor="algo-name" className="text-xs">Name</Label>
            <Input
              id="algo-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="e.g. RSI Pullback in Uptrend"
              className="h-9"
            />
          </div>
          <div className="space-y-1">
            <Label htmlFor="algo-desc" className="text-xs">Idea (optional)</Label>
            <Textarea
              id="algo-desc"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Long when trend is up (EMA20>EMA50) and RSI dips under 40. Short the mirror."
              rows={3}
              className="text-xs"
            />
          </div>

          {preview && (
            <div className="rounded-md border border-primary/30 bg-primary/5 p-3">
              <div className="mb-2 flex items-center justify-between text-[10px] uppercase tracking-widest text-primary">
                <span>Draft spec · {preview.timeframe} · conf {Math.round(preview.confidence * 100)}%</span>
              </div>
              <RuleList title="Long" rules={preview.side_rules.long} />
              <RuleList title="Short" rules={preview.side_rules.short} />
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-2">
          <Button
            variant="outline"
            onClick={generate}
            disabled={loading}
            className="gap-1"
          >
            <Sparkles className="h-3.5 w-3.5" aria-hidden />
            {loading ? "Generating…" : preview ? "Regenerate" : "Generate with AI"}
          </Button>
          <Button onClick={save} disabled={!preview}>
            Save algo
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function RuleList({ title, rules }: { title: string; rules: Array<{ indicator: string; op: string; value: number }> }) {
  if (!rules.length) return (
    <div className="mb-1 text-[11px] text-muted-foreground">
      <span className="font-semibold">{title}:</span> (no rules)
    </div>
  );
  return (
    <div className="mb-1 text-[11px]">
      <span className="font-semibold">{title}:</span>{" "}
      {rules.map((r, i) => (
        <span key={i} className="mr-2 rounded bg-background/60 px-1.5 py-0.5 font-mono">
          {r.indicator} {r.op} {r.value}
        </span>
      ))}
    </div>
  );
}
