"use client";

import { useEffect, useRef, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import {
  detectEntitySlugFromFinding,
  saveFindingToDocs,
} from "@/lib/docs/save-research-finding";

type Focus = "grants" | "vendors" | "compliance" | "competitor" | "general";

interface ResearchFinding {
  title: string;
  summary: string;
  sources?: string[];
  score?: number;
  tags?: string[];
}

interface ResearchResult {
  summary?: string;
  findings?: ResearchFinding[];
  openQuestions?: string[];
  nextSteps?: string[];
}

const FOCUS_OPTIONS: Array<{ value: Focus; label: string; emoji: string; example: string }> = [
  {
    value: "grants",
    label: "Grants",
    emoji: "🎁",
    example: "NC small-business grants for craft beverage manufacturing in Chatham County",
  },
  {
    value: "vendors",
    label: "Vendors",
    emoji: "🤝",
    example: "Co-packers for canned hard seltzer in NC, 1k-10k case run capacity",
  },
  {
    value: "compliance",
    label: "Compliance",
    emoji: "⚖️",
    example: "TTB approval timeline for a wine producer basic permit + NC ABC manufacturer license combo",
  },
  {
    value: "competitor",
    label: "Competitor",
    emoji: "🔭",
    example: "Recent moves by Sake One, Brooklyn Kura, and other US sake producers",
  },
  {
    value: "general",
    label: "General",
    emoji: "📚",
    example: "Best practices for managing 22 small subsidiaries under a single holding co",
  },
];

export function ResearchConsole() {
  const [topic, setTopic] = useState("");
  const [focus, setFocus] = useState<Focus>("general");
  const [context, setContext] = useState("");
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState<ResearchResult | null>(null);
  const [error, setError] = useState<string>("");
  // Per-finding "Save to docs" UX state, keyed by finding index in the
  // current result. Cleared inside `run()` whenever a fresh run lands.
  const [savedKeys, setSavedKeys] = useState<Record<number, true>>({});
  const [justSavedKeys, setJustSavedKeys] = useState<Record<number, true>>({});
  const [entitySelections, setEntitySelections] = useState<Record<number, string>>({});
  const confirmTimers = useRef<Record<number, ReturnType<typeof setTimeout>>>({});

  // Tidy any pending confirm-chip timers on unmount.
  useEffect(() => {
    const timers = confirmTimers.current;
    return () => {
      Object.values(timers).forEach(clearTimeout);
    };
  }, []);

  function clearRowState() {
    setSavedKeys({});
    setJustSavedKeys({});
    setEntitySelections({});
    Object.values(confirmTimers.current).forEach(clearTimeout);
    confirmTimers.current = {};
  }

  function entitySlugFor(key: number, f: ResearchFinding): string {
    if (entitySelections[key]) return entitySelections[key];
    return detectEntitySlugFromFinding(f);
  }

  function handleSaveFinding(key: number, f: ResearchFinding) {
    if (savedKeys[key]) return;
    try {
      saveFindingToDocs(
        {
          title: f.title,
          summary: f.summary,
          sources: f.sources,
          score: f.score,
          tags: f.tags,
          generatedAt: new Date().toISOString(),
        },
        entitySlugFor(key, f),
      );
      setSavedKeys((prev) => ({ ...prev, [key]: true }));
      setJustSavedKeys((prev) => ({ ...prev, [key]: true }));
      if (confirmTimers.current[key]) clearTimeout(confirmTimers.current[key]);
      confirmTimers.current[key] = setTimeout(() => {
        setJustSavedKeys((prev) => {
          const next = { ...prev };
          delete next[key];
          return next;
        });
        delete confirmTimers.current[key];
      }, 4000);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to save to docs");
    }
  }

  async function run() {
    setLoading(true);
    setError("");
    setResult(null);
    clearRowState();
    try {
      const resp = await fetch("/api/research/run", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          topic,
          focus,
          audienceContext: context || undefined,
        }),
      });
      const data = await resp.json();
      if (!resp.ok) throw new Error(data.error || "Research failed");
      setResult((data.result as ResearchResult) ?? null);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed");
    } finally {
      setLoading(false);
    }
  }

  const focusDef = FOCUS_OPTIONS.find((f) => f.value === focus);

  return (
    <div className="space-y-6 max-w-5xl">
      <Card>
        <CardContent className="p-5 space-y-3">
          <div>
            <label className="text-xs text-muted-foreground">Focus</label>
            <div className="mt-1 flex flex-wrap gap-1">
              {FOCUS_OPTIONS.map((f) => {
                const active = focus === f.value;
                return (
                  <button
                    key={f.value}
                    onClick={() => setFocus(f.value)}
                    className={`text-xs px-3 py-1.5 rounded-full border transition-colors inline-flex items-center gap-1 ${
                      active
                        ? "bg-foreground text-background border-foreground"
                        : "border-input text-muted-foreground hover:bg-accent"
                    }`}
                  >
                    <span>{f.emoji}</span>
                    {f.label}
                  </button>
                );
              })}
            </div>
          </div>

          <div>
            <label className="text-xs text-muted-foreground">Topic</label>
            <textarea
              value={topic}
              onChange={(e) => setTopic(e.target.value)}
              rows={2}
              className="mt-1 w-full rounded-md border border-input bg-background p-2 text-sm"
              placeholder={focusDef?.example ?? "What do you want to research?"}
            />
          </div>

          <div>
            <label className="text-xs text-muted-foreground">
              Context (optional — what makes this useful to know)
            </label>
            <textarea
              value={context}
              onChange={(e) => setContext(e.target.value)}
              rows={2}
              className="mt-1 w-full rounded-md border border-input bg-background p-2 text-sm"
              placeholder="e.g. ‘Koshu Sake is launching in Q3 and needs $250k. Focus on NC-specific food & bev grants.’"
            />
          </div>

          <div className="flex items-center justify-between gap-2 flex-wrap">
            <p className="text-[11px] text-muted-foreground">
              Uses Claude with the built-in web_search tool. Capped at 8 searches per run; expect
              30–90 seconds.
            </p>
            <Button
              variant="brand"
              size="sm"
              disabled={loading || !topic.trim()}
              onClick={run}
            >
              {loading ? "Researching…" : "Run research"}
            </Button>
          </div>
          {error && <p className="text-xs text-destructive">{error}</p>}
        </CardContent>
      </Card>

      {result && (
        <>
          {result.summary && (
            <Card>
              <CardContent className="p-5">
                <h2 className="text-base font-semibold mb-2">Executive summary</h2>
                <p className="text-sm leading-relaxed">{result.summary}</p>
              </CardContent>
            </Card>
          )}

          {result.findings && result.findings.length > 0 && (
            <div className="space-y-3">
              <h2 className="text-base font-semibold">
                Findings ({result.findings.length})
              </h2>
              {result.findings
                .slice()
                .sort((a, b) => (b.score ?? 0) - (a.score ?? 0))
                .map((f, i) => {
                  const saved = Boolean(savedKeys[i]);
                  const justSaved = Boolean(justSavedKeys[i]);
                  const selectedSlug = entitySlugFor(i, f);
                  return (
                    <Card key={i}>
                      <CardContent className="p-5 space-y-2">
                        <div className="flex items-start justify-between gap-2 flex-wrap">
                          <h3 className="text-sm font-semibold">{f.title}</h3>
                          {typeof f.score === "number" && (
                            <Badge variant={f.score >= 7 ? "success" : "outline"}>
                              score {f.score}/10
                            </Badge>
                          )}
                        </div>
                        <p className="text-sm leading-relaxed">{f.summary}</p>
                        {f.tags && f.tags.length > 0 && (
                          <div className="flex flex-wrap gap-1">
                            {f.tags.map((t) => (
                              <Badge key={t} variant="outline" className="text-[10px]">
                                {t}
                              </Badge>
                            ))}
                          </div>
                        )}
                        {f.sources && f.sources.length > 0 && (
                          <div className="pt-1 flex flex-wrap gap-2">
                            {f.sources.map((s, j) => (
                              <a
                                key={j}
                                href={s}
                                target="_blank"
                                rel="noopener noreferrer"
                                className="text-[11px] text-[var(--sag-brand)] hover:underline truncate max-w-[28rem]"
                              >
                                ↗ {s}
                              </a>
                            ))}
                          </div>
                        )}
                        <div className="pt-2 flex items-center gap-2 flex-wrap border-t border-border/40 mt-2">
                          <label className="section-label">
                            Save under
                          </label>
                          <select
                            value={selectedSlug}
                            onChange={(e) =>
                              setEntitySelections((prev) => ({
                                ...prev,
                                [i]: e.target.value,
                              }))
                            }
                            disabled={saved}
                            className="h-8 rounded-md border border-input bg-background px-2 text-xs"
                            aria-label="Entity to attribute this finding to"
                          >
                            {ALL_ORGANIZATIONS.map((o) => (
                              <option key={o.slug} value={o.slug}>
                                {o.emoji ?? ""} {o.name}
                              </option>
                            ))}
                          </select>
                          <Button
                            variant="outline"
                            size="sm"
                            disabled={saved}
                            onClick={() => handleSaveFinding(i, f)}
                          >
                            {saved ? "Saved" : "Save to docs"}
                          </Button>
                          {justSaved && (
                            <Badge variant="success" className="text-[10px]">
                              Saved to docs
                            </Badge>
                          )}
                          {saved && !justSaved && (
                            <span className="text-[11px] text-muted-foreground">
                              Already saved
                            </span>
                          )}
                        </div>
                      </CardContent>
                    </Card>
                  );
                })}
            </div>
          )}

          {result.nextSteps && result.nextSteps.length > 0 && (
            <Card>
              <CardContent className="p-5">
                <h2 className="text-base font-semibold mb-2">Recommended next steps</h2>
                <ul className="text-sm space-y-1 list-disc pl-5">
                  {result.nextSteps.map((s, i) => (
                    <li key={i}>{s}</li>
                  ))}
                </ul>
              </CardContent>
            </Card>
          )}

          {result.openQuestions && result.openQuestions.length > 0 && (
            <Card>
              <CardContent className="p-5">
                <h2 className="text-base font-semibold mb-2">Open questions</h2>
                <ul className="text-sm space-y-1 list-disc pl-5">
                  {result.openQuestions.map((q, i) => (
                    <li key={i}>{q}</li>
                  ))}
                </ul>
              </CardContent>
            </Card>
          )}
        </>
      )}

      <Card className="border-dashed">
        <CardContent className="p-5 text-xs text-muted-foreground">
          Inspired by{" "}
          <a
            href="https://github.com/karpathy/autoresearch"
            target="_blank"
            rel="noopener noreferrer"
            className="underline"
          >
            karpathy/autoresearch
          </a>
          . Web-search runs server-side via Claude&rsquo;s built-in tool — no separate search API
          key needed.
        </CardContent>
      </Card>
    </div>
  );
}
