"use client";

/**
 * Keyword Research — AI-powered keyword intelligence page.
 * Combines SERP-provider data (or AI estimates) with Claude strategic
 * analysis: topic clusters, quick wins, gap analysis, content plan.
 */

import { useCallback, useEffect, useMemo, useState, useRef } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import { useBrand } from "@/context/brand-context";
import { useBackgroundTasks } from "@/lib/stores/task-store";
import {
  Search, Loader2, Sparkles, TrendingUp, Target, AlertTriangle, HelpCircle,
  ChevronDown, BarChart3, MapPin, Bot,
} from "lucide-react";
import LocationSearch from "@/components/keyword-research/location-search";

import StrategySummary from "@/components/keyword-research/strategy-summary";
import TopicClusterCard from "@/components/keyword-research/topic-cluster-card";
import KeywordTable, { type KwRow } from "@/components/keyword-research/keyword-table";
import ContentPlan from "@/components/keyword-research/content-plan";
import BulkActionBar from "@/components/keyword-research/bulk-action-bar";
import { useAiIndicators } from "@/hooks/useAiIndicators";
import { AiBadgesForItem } from "@/components/ai-badge";

// ─── Types ─────────────────────────────────────────────────────────────────────

interface Kw { keyword: string; searchVolume?: number | null; difficulty?: number | null; cpc?: number | null; intent?: string | null; source?: string }
interface Analysis {
  summary: string;
  topicClusters: Array<{ name: string; keywords: string[]; contentStrategy: string; priority: string; estimatedTrafficPotential: string }>;
  quickWins: Array<{ keyword: string; currentPosition?: number; volume?: number; action: string }>;
  gapAnalysis: Array<{ keyword: string; volume?: number; difficulty?: number; reason: string }>;
  questionKeywords: Array<{ question: string; volume?: number; suggestedContentType: string }>;
  avoidKeywords: Array<{ keyword: string; reason: string }>;
  contentPlan: Array<{ title: string; targetKeyword: string; relatedKeywords: string[]; intent: string; format: string; priority: string }>;
}

interface Result { keywords: Kw[]; aiAnalysis: Analysis; cached: boolean; source: string }

// Location is now handled by the LocationSearch component
const LOADING_MSGS = ["Analyzing search landscape...", "Identifying topic clusters...", "Evaluating competition...", "Building content plan..."];

// ─── Page ──────────────────────────────────────────────────────────────────────

interface AiSuggestions { branded: string[]; nonBranded: string[] }

export default function KeywordResearchPage() {
  const { brand } = useBrand();
  const { addTask, completeTask, failTask } = useBackgroundTasks();
  const router = useRouter();
  // Deep link support — /keyword-research?keyword=X (sent by Topic
  // Map, Execution Hub, etc.). Also honour the legacy `seed` name
  // because the Topic Map used it briefly in an earlier revision.
  const searchParams = useSearchParams();
  const initialKeyword = (searchParams.get("keyword") || searchParams.get("seed") || "").trim();
  const autoAnalyzedRef = useRef(false);
  const historyLoadedRef = useRef(false);
  const [seed, setSeed] = useState(initialKeyword);
  const [location, setLocation] = useState("United States");
  const [locationDisplay, setLocationDisplay] = useState("United States");
  const [result, setResult] = useState<Result | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadingMsg, setLoadingMsg] = useState("");
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [showAvoid, setShowAvoid] = useState(false);
  const [history, setHistory] = useState<Array<{ seed: string; date: string; count: number }>>([]);
  const [aiSuggestions, setAiSuggestions] = useState<AiSuggestions | null>(null);
  const [suggestionsLoading, setSuggestionsLoading] = useState(false);
  /** Lowercased set of keywords already in the brand's Rank Tracker. Seeds
   *  the inline "Tracking ✓" badge so users don't re-track dupes. Loaded
   *  once per brand; updated optimistically on Track click + Bulk Track. */
  const [trackedKeywords, setTrackedKeywords] = useState<Set<string>>(new Set());

  // Load the brand's existing Rank Tracker keywords once the brand is
  // resolved. Refetches on brand switch.
  useEffect(() => {
    if (!brand.id) return;
    let cancelled = false;
    fetch(`/api/rank-tracking/keywords?brandId=${brand.id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (cancelled || !data) return;
        const list = Array.isArray(data) ? data : (data.keywords ?? []);
        setTrackedKeywords(new Set(list.map((k: { keyword: string }) => k.keyword.toLowerCase())));
      })
      .catch(() => { /* best-effort */ });
    return () => { cancelled = true; };
  }, [brand.id]);

  // Load search history from DB on mount (once per brand)
  useEffect(() => {
    if (!brand.id || historyLoadedRef.current) return;
    historyLoadedRef.current = true;
    fetch(`/api/keyword-research/analyze?brandId=${brand.id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (data?.history?.length) {
          setHistory(data.history.map((h: { seed: string; date: string; count: number }) => ({
            seed: h.seed, date: h.date, count: h.count,
          })));
        }
      })
      .catch(() => { /* best-effort */ });
  }, [brand.id]);

  // Load AI keyword suggestions for this brand (deferred — shown on empty state)
  useEffect(() => {
    if (!brand.id || aiSuggestions || suggestionsLoading) return;
    setSuggestionsLoading(true);
    fetch(`/api/keyword-research/suggestions?brandId=${brand.id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (data) setAiSuggestions(data);
      })
      .catch(() => { /* best-effort */ })
      .finally(() => setSuggestionsLoading(false));
  // Run once per brand — don't include aiSuggestions/suggestionsLoading in deps
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [brand.id]);

  /** Track a single keyword — called from the per-row Track button in the
   *  keyword table. Optimistically flips the UI to "Tracking ✓", POSTs to
   *  Rank Tracker, then navigates to /rank-tracker so the user can see
   *  their new keyword and trigger a rank check. Rolls back on failure. */
  const trackOne = useCallback(async (keyword: string) => {
    const key = keyword.toLowerCase();
    if (trackedKeywords.has(key)) {
      router.push(`/rank-tracker`);
      return;
    }
    setTrackedKeywords((prev) => { const n = new Set(prev); n.add(key); return n; });
    try {
      const res = await fetch("/api/rank-tracking/keywords", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId: brand.id, keywords: [{ keyword }] }),
      });
      if (!res.ok) throw new Error("track failed");
      router.push(`/rank-tracker`);
    } catch {
      setTrackedKeywords((prev) => { const n = new Set(prev); n.delete(key); return n; });
    }
  }, [brand.id, trackedKeywords, router]);

  // ── Search ──
  const analyze = useCallback(async (seedKw?: string) => {
    const kw = seedKw || seed.trim();
    if (!kw || loading) return;
    setSeed(kw);
    router.replace(`/keyword-research?keyword=${encodeURIComponent(kw)}`, { scroll: false });
    setLoading(true); setResult(null); setSelected(new Set());
    let msgIdx = 0;
    setLoadingMsg(LOADING_MSGS[0]);
    const interval = setInterval(() => { msgIdx = (msgIdx + 1) % LOADING_MSGS.length; setLoadingMsg(LOADING_MSGS[msgIdx]); }, 3000);
    const taskId = addTask({ id: `kw_${Date.now()}`, type: "keyword_research", label: `Analyzing "${kw}"...`, brandId: brand.id, resultUrl: "/keyword-research" });
    try {
      const res = await fetch("/api/keyword-research/analyze", {
        method: "POST", headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId: brand.id, seedKeyword: kw, location }),
      });
      if (res.ok) {
        const data = await res.json() as Result;
        setResult(data);
        setHistory((h) => [{ seed: kw, date: new Date().toISOString(), count: data.keywords.length }, ...h.filter((x) => x.seed !== kw).slice(0, 9)]);
        completeTask(taskId, { resultUrl: "/keyword-research", resultSummary: `Found ${data.keywords.length} keywords for "${kw}"` });
      } else { failTask(taskId, "Analysis failed"); }
    } catch { failTask(taskId, "Network error"); }
    clearInterval(interval); setLoading(false);
  }, [seed, brand.id, location, loading, addTask, completeTask, failTask, router]);

  // Auto-run analysis once when the page is opened with ?keyword=X.
  // Guarded by a ref so refreshing the brand context / switching
  // brands doesn't re-trigger on a keyword the user already saw.
  useEffect(() => {
    if (!initialKeyword || autoAnalyzedRef.current) return;
    if (!brand.id) return; // wait for brand context to resolve
    autoAnalyzedRef.current = true;
    analyze(initialKeyword);
  // analyze intentionally omitted — its deps (including loading)
  // would re-fire this effect mid-run.
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [initialKeyword, brand.id]);

  const toggleKw = useCallback((kw: string) => {
    setSelected((prev) => { const n = new Set(prev); n.has(kw) ? n.delete(kw) : n.add(kw); return n; });
  }, []);

  const selectedKws = useMemo(() => {
    if (!result) return [];
    const kwMap = new Map(result.keywords.map((k) => [k.keyword.toLowerCase(), k]));
    return Array.from(selected).map((kw) => kwMap.get(kw.toLowerCase()) || { keyword: kw }).map((k) => ({ keyword: k.keyword, searchVolume: k.searchVolume, difficulty: k.difficulty, intent: k.intent, source: k.source }));
  }, [selected, result]);

  // Map analysis lists to KwRow for the table component
  // Build a keyword→intent lookup from the full keyword list
  const intentMap = new Map<string, string>();
  if (result?.keywords) {
    for (const k of result.keywords) {
      if (k.intent) intentMap.set(k.keyword.toLowerCase(), k.intent);
    }
  }

  const quickWinRows: KwRow[] = result?.aiAnalysis?.quickWins?.map((w) => ({ keyword: w.keyword, volume: w.volume, position: w.currentPosition, action: w.action, intent: intentMap.get(w.keyword.toLowerCase()) ?? undefined })) ?? [];
  const gapRows: KwRow[] = result?.aiAnalysis?.gapAnalysis?.map((g) => ({ keyword: g.keyword, volume: g.volume, difficulty: g.difficulty, reason: g.reason, intent: intentMap.get(g.keyword.toLowerCase()) ?? undefined })) ?? [];
  const questionRows: KwRow[] = result?.aiAnalysis?.questionKeywords?.map((q) => ({ keyword: q.question, volume: q.volume, contentType: q.suggestedContentType, intent: "informational" })) ?? [];
  const avoidRows: KwRow[] = result?.aiAnalysis?.avoidKeywords?.map((a) => ({ keyword: a.keyword, reason: a.reason })) ?? [];

  // AI indicator data for all keywords in results
  const aiIndicatorItems = useMemo(() => {
    if (!result?.keywords) return [];
    return result.keywords.map((k) => ({ type: "keyword" as const, value: k.keyword }));
  }, [result]);
  const aiIndicators = useAiIndicators(brand.id, aiIndicatorItems);

  const aiSummary = useMemo(() => {
    if (aiIndicators.loading || !result) return null;
    const kws = Object.values(aiIndicators.keywords);
    const cited = kws.filter((k) => k.cited).length;
    const withTraffic = kws.filter((k) => k.aiVisits > 0).length;
    const topConverting = Object.entries(aiIndicators.keywords)
      .filter(([, d]) => d.aiConversions > 0)
      .sort((a, b) => b[1].aiConversions - a[1].aiConversions)[0];
    const opportunities = kws.filter((k) => k.opportunity).length;
    if (cited === 0 && withTraffic === 0) return null;
    return { cited, total: kws.length, withTraffic, topConverting, opportunities };
  }, [aiIndicators, result]);

  return (
    <div className="space-y-6 max-w-6xl">
      {/* Header + Search */}
      <div>
        <h1 className="text-2xl font-bold text-slate-900">Keyword Research</h1>
        <p className="text-slate-500 text-sm mt-1">AI-powered keyword intelligence for {brand.domain}</p>
      </div>

      <div className="flex items-center gap-3">
        <div className="relative flex-1">
          <Search className="w-4 h-4 text-slate-400 absolute left-4 top-1/2 -translate-y-1/2" />
          <input value={seed} onChange={(e) => setSeed(e.target.value)} onKeyDown={(e) => e.key === "Enter" && analyze()} placeholder="Enter a keyword, topic, or phrase..." className="w-full pl-11 pr-4 py-3 text-sm border border-slate-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-brand-500/40 focus:border-brand-500 bg-white" />
        </div>
        <div className="w-56 shrink-0">
          <LocationSearch value={location} onChange={(apiName, display) => { setLocation(apiName); setLocationDisplay(display); }} brandLocation={brand.name} />
        </div>
        <button onClick={() => analyze()} disabled={loading || !seed.trim()} className="flex items-center gap-2 px-6 py-3 bg-brand-600 text-white text-sm font-semibold rounded-xl hover:bg-brand-700 disabled:opacity-50">
          {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Sparkles className="w-4 h-4" />}
          {loading ? "Analyzing..." : "Analyze"}
        </button>
      </div>

      {/* AI-suggested keyword chips — shown when not loading and no result */}
      {!loading && !result && aiSuggestions && (aiSuggestions.branded.length > 0 || aiSuggestions.nonBranded.length > 0) && (
        <div className="space-y-2">
          {aiSuggestions.branded.length > 0 && (
            <div>
              <p className="text-[10px] font-bold uppercase tracking-widest text-purple-400 mb-1.5">Branded suggestions</p>
              <div className="flex flex-wrap gap-1.5">
                {aiSuggestions.branded.map((kw) => (
                  <button key={kw} onClick={() => analyze(kw)} className="px-2.5 py-1 text-xs font-medium rounded-full border border-purple-200 bg-purple-50 text-purple-700 hover:bg-purple-100 transition-colors">
                    {kw}
                  </button>
                ))}
              </div>
            </div>
          )}
          {aiSuggestions.nonBranded.length > 0 && (
            <div>
              <p className="text-[10px] font-bold uppercase tracking-widest text-teal-400 mb-1.5">Topic suggestions</p>
              <div className="flex flex-wrap gap-1.5">
                {aiSuggestions.nonBranded.map((kw) => (
                  <button key={kw} onClick={() => analyze(kw)} className="px-2.5 py-1 text-xs font-medium rounded-full border border-teal-200 bg-teal-50 text-teal-700 hover:bg-teal-100 transition-colors">
                    {kw}
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
      )}
      {!loading && !result && suggestionsLoading && (
        <div className="flex items-center gap-2 text-xs text-slate-400">
          <Loader2 className="w-3 h-3 animate-spin" /> Loading keyword suggestions…
        </div>
      )}

      {/* Loading state */}
      {loading && (
        <div className="bg-white rounded-xl border border-slate-200 px-8 py-16 text-center">
          <Loader2 className="w-8 h-8 text-brand-600 animate-spin mx-auto mb-4" />
          <p className="text-sm font-semibold text-slate-700 mb-1">{loadingMsg}</p>
          <p className="text-xs text-slate-400">This takes 10-20 seconds — the AI is analyzing the full keyword landscape.</p>
        </div>
      )}

      {/* History pills */}
      {!result && !loading && history.length > 0 && (
        <div>
          <p className="text-[10px] font-bold uppercase tracking-widest text-slate-400 mb-2">Recent searches</p>
          <div className="flex flex-wrap gap-2">
            {history.map((h) => (
              <button key={h.seed} onClick={() => { setSeed(h.seed); analyze(h.seed); }} className="px-3 py-1.5 rounded-lg bg-white border border-slate-200 text-xs font-medium text-slate-700 hover:border-brand-300 hover:bg-brand-50">
                {h.seed} <span className="text-slate-400">· {h.count} kws</span>
              </button>
            ))}
          </div>
        </div>
      )}

      {/* Empty state */}
      {!result && !loading && history.length === 0 && (
        <div className="bg-white rounded-xl border border-slate-200 px-8 py-16 text-center">
          <Search className="w-14 h-14 text-slate-200 mx-auto mb-4" />
          <h2 className="text-lg font-bold text-slate-900 mb-1">Start Your Keyword Research</h2>
          <p className="text-sm text-slate-500 max-w-md mx-auto">Enter a keyword or topic above. The AI will analyze search volume, difficulty, topic clusters, competitive gaps, and build a content plan — like consulting a senior SEO strategist.</p>
        </div>
      )}

      {/* Results */}
      {result && result.aiAnalysis && (
        <div className="space-y-5">
          {/* Summary */}
          <StrategySummary summary={result.aiAnalysis.summary || ""} keywordCount={result.keywords?.length ?? 0} clusterCount={result.aiAnalysis.topicClusters?.length ?? 0} quickWinCount={result.aiAnalysis.quickWins?.length ?? 0} source={result.source} cached={result.cached} onRefresh={() => analyze()} />

          {/* AI Performance Summary */}
          {aiSummary && (
            <div className="bg-gradient-to-r from-violet-50 to-blue-50 border border-violet-200 rounded-xl px-5 py-3 flex items-center gap-4 flex-wrap">
              <div className="flex items-center gap-1.5">
                <Bot className="w-4 h-4 text-violet-600" />
                <span className="text-xs font-bold text-violet-700">AI Intelligence</span>
              </div>
              <span className="text-xs text-slate-600">
                <span className="font-semibold text-emerald-700">{aiSummary.cited}</span> of {aiSummary.total} keywords cited by AI
              </span>
              {aiSummary.topConverting && (
                <span className="text-xs text-slate-600">
                  Top: <span className="font-semibold text-violet-700">{aiSummary.topConverting[0]}</span> — {aiSummary.topConverting[1].aiConversions} conv.
                </span>
              )}
              {aiSummary.opportunities > 0 && (
                <span className="text-xs text-orange-600 font-semibold">
                  {aiSummary.opportunities} AI opportunities
                </span>
              )}
            </div>
          )}

          {locationDisplay !== "United States" && (
            <p className="text-xs text-slate-500 -mt-3 flex items-center gap-1"><MapPin className="w-3 h-3" /> Showing data for <span className="font-semibold text-slate-700">{locationDisplay}</span>. National volume may differ.</p>
          )}

          {/* Topic clusters */}
          {(result.aiAnalysis.topicClusters?.length ?? 0) > 0 && (
            <div>
              <h2 className="text-xs font-bold uppercase tracking-widest text-slate-400 mb-3">Topic Clusters</h2>
              <div className="space-y-2">
                {result.aiAnalysis.topicClusters.map((cluster, i) => (
                  <TopicClusterCard key={i} cluster={cluster} allKeywords={result.keywords} selected={selected} onToggle={toggleKw} />
                ))}
              </div>
            </div>
          )}

          {/* Quick Wins */}
          {quickWinRows.length > 0 && (
            <div>
              <div className="flex items-center gap-2 mb-3"><TrendingUp className="w-4 h-4 text-green-600" /><h2 className="text-xs font-bold uppercase tracking-widest text-slate-400">Quick Wins</h2></div>
              <KeywordTable rows={quickWinRows} columns={[{ key: "keyword", label: "Keyword" }, { key: "position", label: "Position" }, { key: "volume", label: "Volume" }, { key: "action", label: "Action" }, { key: "track", label: "Rank Tracker" }]} selected={selected} onToggle={toggleKw} accent="border-green-200" trackedKeywords={trackedKeywords} onTrack={trackOne} aiData={aiIndicators.keywords} />
            </div>
          )}

          {/* Gap Analysis */}
          {gapRows.length > 0 && (
            <div>
              <div className="flex items-center gap-2 mb-3"><Target className="w-4 h-4 text-blue-600" /><h2 className="text-xs font-bold uppercase tracking-widest text-slate-400">Gap Analysis</h2></div>
              <KeywordTable rows={gapRows} columns={[{ key: "keyword", label: "Keyword" }, { key: "volume", label: "Volume" }, { key: "difficulty", label: "Difficulty" }, { key: "reason", label: "Gap Reason" }, { key: "track", label: "Rank Tracker" }]} selected={selected} onToggle={toggleKw} accent="border-blue-200" trackedKeywords={trackedKeywords} onTrack={trackOne} aiData={aiIndicators.keywords} />
            </div>
          )}

          {/* Questions */}
          {questionRows.length > 0 && (
            <div>
              <div className="flex items-center gap-2 mb-3"><HelpCircle className="w-4 h-4 text-violet-600" /><h2 className="text-xs font-bold uppercase tracking-widest text-slate-400">People Also Ask</h2></div>
              <KeywordTable rows={questionRows} columns={[{ key: "keyword", label: "Question" }, { key: "volume", label: "Volume" }, { key: "contentType", label: "Content Type" }, { key: "track", label: "Rank Tracker" }]} selected={selected} onToggle={toggleKw} accent="border-violet-200" trackedKeywords={trackedKeywords} onTrack={trackOne} aiData={aiIndicators.keywords} />
            </div>
          )}

          {/* Content Plan */}
          <ContentPlan items={result.aiAnalysis.contentPlan ?? []} brandId={brand.id} />

          {/* Avoid list */}
          {avoidRows.length > 0 && (
            <div>
              <button onClick={() => setShowAvoid(!showAvoid)} className="flex items-center gap-2 text-xs font-semibold text-slate-500 hover:text-slate-700 mb-2">
                <AlertTriangle className="w-3.5 h-3.5 text-slate-400" />
                {showAvoid ? "Hide" : "Show"} {avoidRows.length} keywords to avoid
                <ChevronDown className={`w-3.5 h-3.5 transition-transform ${showAvoid ? "rotate-180" : ""}`} />
              </button>
              {showAvoid && <KeywordTable rows={avoidRows} columns={[{ key: "keyword", label: "Keyword" }, { key: "reason", label: "Reason" }]} selected={selected} onToggle={toggleKw} accent="border-slate-300" />}
            </div>
          )}
        </div>
      )}

      {/* Bulk action bar */}
      <BulkActionBar
        count={selected.size}
        brandId={brand.id}
        selectedKeywords={selectedKws}
        onSaved={() => setSelected(new Set())}
        onClear={() => setSelected(new Set())}
        onTracked={(kws) => setTrackedKeywords((prev) => {
          const n = new Set(prev);
          for (const kw of kws) n.add(kw.toLowerCase());
          return n;
        })}
      />
    </div>
  );
}
