"use client";

import { useState, useCallback } from "react";
import { X, Plus, Loader2, Sparkles, Check, ChevronDown, ChevronRight, Target, Globe, MapPin, Languages } from "lucide-react";

const COUNTRIES = [
  "United States", "United Kingdom", "Canada", "Australia", "Germany",
  "France", "Spain", "Italy", "Netherlands", "Brazil", "India", "Japan",
];

// ─── Suggestion types (mirror the API response) ─────────────────────────────

interface Suggestion {
  keyword: string;
  source: string;
  impressions: number | null;
  currentPosition: number | null;
  priority: string;
  reason: string;
  targetUrl?: string;
  suggestedTags?: string[];
}

interface SuggestionsData {
  branded: Suggestion[];
  nonBranded: Suggestion[];
  localVariations: Suggestion[];
  spanishKeywords: Suggestion[];
  strikingDistance: Suggestion[];
  total: number;
}

type CategoryKey = keyof Omit<SuggestionsData, "total">;

const CATEGORY_META: Record<CategoryKey, { label: string; icon: typeof Target; color: string }> = {
  branded:          { label: "Branded",           icon: Target,    color: "text-violet-600 bg-violet-50 border-violet-200" },
  nonBranded:       { label: "Non-Branded",       icon: Globe,     color: "text-blue-600 bg-blue-50 border-blue-200" },
  strikingDistance:  { label: "Striking Distance", icon: Target,    color: "text-amber-600 bg-amber-50 border-amber-200" },
  localVariations:  { label: "Local",             icon: MapPin,    color: "text-emerald-600 bg-emerald-50 border-emerald-200" },
  spanishKeywords:  { label: "Spanish",           icon: Languages, color: "text-rose-600 bg-rose-50 border-rose-200" },
};

const PRIORITY_DOT: Record<string, string> = {
  track: "bg-violet-500",
  high: "bg-red-500",
  medium: "bg-amber-500",
  low: "bg-slate-400",
};

// ─── Component ──────────────────────────────────────────────────────────────

interface Props {
  brandId: string;
  open: boolean;
  onClose: () => void;
  onAdded: () => void;
}

export default function AddKeywordsModal({ brandId, open, onClose, onAdded }: Props) {
  // Manual entry state
  const [text, setText] = useState("");
  const [location, setLocation] = useState("United States");
  const [customLocation, setCustomLocation] = useState("");
  const [device, setDevice] = useState<"desktop" | "mobile">("desktop");
  const [targetUrl, setTargetUrl] = useState("");
  const [tags, setTags] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // AI suggestions state
  const [suggestions, setSuggestions] = useState<SuggestionsData | null>(null);
  const [sugLoading, setSugLoading] = useState(false);
  const [aiLoading, setAiLoading] = useState(false);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [expanded, setExpanded] = useState<Set<CategoryKey>>(new Set(["nonBranded", "strikingDistance"]));

  /** Merge incoming AI suggestions into the current results. */
  function mergeSuggestions(base: SuggestionsData, ai: SuggestionsData): SuggestionsData {
    const existing = new Set<string>();
    for (const cat of Object.keys(CATEGORY_META) as CategoryKey[]) {
      for (const s of base[cat]) existing.add(s.keyword.toLowerCase());
    }
    const merged = { ...base, total: base.total };
    for (const cat of Object.keys(CATEGORY_META) as CategoryKey[]) {
      const fresh = ai[cat].filter((s) => !existing.has(s.keyword.toLowerCase()));
      if (fresh.length > 0) {
        merged[cat] = [...base[cat], ...fresh];
        merged.total += fresh.length;
      }
    }
    return merged;
  }

  function autoSelectHighPriority(data: SuggestionsData) {
    const auto = new Set<string>();
    for (const cat of Object.keys(CATEGORY_META) as CategoryKey[]) {
      for (const s of data[cat]) {
        if (s.priority === "high" || s.priority === "track") auto.add(s.keyword);
      }
    }
    return auto;
  }

  // ── Two-phase fetch: instant GSC+SiteTag, then AI in background ───
  // NOTE: useCallback must be declared before any early return to satisfy Rules of Hooks.
  const fetchSuggestions = useCallback(async () => {
    setSugLoading(true);
    try {
      // Phase 1: GSC + Site Tag only (fast, no AI call)
      const fastRes = await fetch(`/api/rank-tracking/suggestions?brandId=${brandId}&includeAi=false`);
      if (fastRes.ok) {
        const fastData: SuggestionsData = await fastRes.json();
        setSuggestions(fastData);
        setSelected(autoSelectHighPriority(fastData));
      }
    } catch { /* swallow */ }
    setSugLoading(false);

    // Phase 2: AI enrichment (background — appends to existing results)
    setAiLoading(true);
    try {
      const aiRes = await fetch(`/api/rank-tracking/suggestions?brandId=${brandId}&includeAi=true`);
      if (aiRes.ok) {
        const aiData: SuggestionsData = await aiRes.json();
        setSuggestions((prev) => {
          if (!prev) return aiData;
          return mergeSuggestions(prev, aiData);
        });
        // Auto-select high-priority AI suggestions OUTSIDE the
        // setSuggestions updater — calling setState inside another
        // setState's updater function can trigger React Error #310
        // (too many re-renders) under strict mode or concurrent mode.
        setSelected((prevSel) => {
          const next = new Set(prevSel);
          for (const cat of Object.keys(CATEGORY_META) as CategoryKey[]) {
            for (const s of aiData[cat]) {
              if ((s.priority === "high" || s.priority === "track") && s.source === "ai") next.add(s.keyword);
            }
          }
          return next;
        });
      }
    } catch { /* AI unavailable — fast results are already displayed */ }
    setAiLoading(false);
  }, [brandId]);

  if (!open) return null;

  const keywords = text.split("\n").map((l) => l.trim()).filter(Boolean);
  const loc = location === "Custom" ? customLocation.trim() || "United States" : location;

  // ── Add selected suggestions to the textarea ─────────────────────
  function addSelectedToText() {
    if (selected.size === 0) return;
    const existing = new Set(keywords.map((k) => k.toLowerCase()));
    const toAdd = [...selected].filter((kw) => !existing.has(kw.toLowerCase()));
    if (toAdd.length === 0) return;
    setText((prev) => {
      const trimmed = prev.trim();
      return trimmed ? `${trimmed}\n${toAdd.join("\n")}` : toAdd.join("\n");
    });
    if (!tags && suggestions) {
      const allSugg = [...suggestions.branded, ...suggestions.nonBranded, ...suggestions.localVariations, ...suggestions.spanishKeywords, ...suggestions.strikingDistance];
      const first = allSugg.find((s) => selected.has(s.keyword) && s.suggestedTags?.length);
      if (first?.suggestedTags) setTags(first.suggestedTags.join(", "));
    }
  }

  function toggleKeyword(kw: string) {
    setSelected((prev) => { const n = new Set(prev); if (n.has(kw)) n.delete(kw); else n.add(kw); return n; });
  }
  function selectAllInCategory(cat: CategoryKey) {
    if (!suggestions) return;
    setSelected((prev) => { const n = new Set(prev); for (const s of suggestions[cat]) n.add(s.keyword); return n; });
  }
  function toggleCategory(cat: CategoryKey) {
    setExpanded((prev) => { const n = new Set(prev); if (n.has(cat)) n.delete(cat); else n.add(cat); return n; });
  }

  async function submit() {
    if (keywords.length === 0) return;
    setLoading(true); setError(null);
    try {
      const res = await fetch("/api/rank-tracking/keywords", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          brandId,
          keywords: keywords.map((kw) => ({
            keyword: kw, location: loc, device,
            targetUrl: targetUrl.trim() || undefined,
            tags: tags ? tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
          })),
        }),
      });
      if (!res.ok) { const d = await res.json().catch(() => ({})); throw new Error(d.error || "Failed"); }
      onAdded(); onClose();
      setText(""); setTags(""); setTargetUrl(""); setSuggestions(null); setSelected(new Set());
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to add keywords");
    } finally { setLoading(false); }
  }

  // Selection summary counts
  function countSelected() {
    if (!suggestions) return { branded: 0, nonBranded: 0, local: 0, spanish: 0, striking: 0, total: selected.size };
    const sets: Record<string, Set<string>> = {};
    for (const cat of Object.keys(CATEGORY_META) as CategoryKey[]) sets[cat] = new Set(suggestions[cat].map((s) => s.keyword));
    let branded = 0, nonBranded = 0, local = 0, spanish = 0, striking = 0;
    for (const kw of selected) {
      if (sets.branded.has(kw)) branded++;
      else if (sets.strikingDistance.has(kw)) striking++;
      else if (sets.localVariations.has(kw)) local++;
      else if (sets.spanishKeywords.has(kw)) spanish++;
      else nonBranded++;
    }
    return { branded, nonBranded, local, spanish, striking, total: selected.size };
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/60 p-4" onClick={onClose}>
      <div className="bg-white rounded-2xl shadow-2xl w-full max-w-2xl overflow-hidden max-h-[90vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between border-b border-slate-200 px-5 py-4 shrink-0">
          <h2 className="font-bold text-slate-900">Add Keywords</h2>
          <button onClick={onClose} className="p-1.5 rounded-lg hover:bg-slate-100 text-slate-500"><X className="w-4 h-4" /></button>
        </div>

        <div className="flex-1 overflow-y-auto p-5 space-y-4">
          {/* AI Suggestions panel */}
          <div className="bg-gradient-to-r from-indigo-50 to-violet-50 rounded-xl border border-indigo-200 overflow-hidden">
            <div className="px-4 py-3 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Sparkles className="w-4 h-4 text-indigo-500" />
                <span className="text-xs font-bold text-indigo-900">AI Keyword Suggestions</span>
                {suggestions && (
                  <span className="text-[10px] text-indigo-500 font-semibold">
                    {suggestions.total} found{aiLoading && " · AI analyzing..."}
                  </span>
                )}
              </div>
              {!suggestions && (
                <button onClick={fetchSuggestions} disabled={sugLoading} className="flex items-center gap-1.5 px-3 py-1.5 bg-indigo-600 text-white text-[11px] font-semibold rounded-lg hover:bg-indigo-700 disabled:opacity-60">
                  {sugLoading ? <Loader2 className="w-3 h-3 animate-spin" /> : <Sparkles className="w-3 h-3" />}
                  {sugLoading ? "Analyzing..." : "Get Suggestions"}
                </button>
              )}
              {suggestions && selected.size > 0 && (
                <button onClick={addSelectedToText} className="flex items-center gap-1.5 px-3 py-1.5 bg-indigo-600 text-white text-[11px] font-semibold rounded-lg hover:bg-indigo-700">
                  <Plus className="w-3 h-3" /> Add {selected.size} Selected
                </button>
              )}
            </div>

            {suggestions && (
              <div className="border-t border-indigo-200 divide-y divide-indigo-100">
                {(Object.keys(CATEGORY_META) as CategoryKey[]).map((cat) => {
                  const items = suggestions[cat];
                  if (items.length === 0) return null;
                  const meta = CATEGORY_META[cat];
                  const Icon = meta.icon;
                  const isExpanded = expanded.has(cat);
                  const selectedInCat = items.filter((s) => selected.has(s.keyword)).length;
                  return (
                    <div key={cat}>
                      <button onClick={() => toggleCategory(cat)} className="w-full px-4 py-2.5 flex items-center gap-2 text-left hover:bg-indigo-50/50">
                        {isExpanded ? <ChevronDown className="w-3 h-3 text-slate-400" /> : <ChevronRight className="w-3 h-3 text-slate-400" />}
                        <Icon className="w-3.5 h-3.5 text-slate-500" />
                        <span className="text-[11px] font-bold text-slate-800">{meta.label}</span>
                        <span className={`text-[10px] font-bold px-1.5 py-0.5 rounded border ${meta.color}`}>{items.length}</span>
                        {selectedInCat > 0 && <span className="text-[10px] font-semibold text-indigo-600 ml-auto">{selectedInCat} selected</span>}
                        <span onClick={(e) => { e.stopPropagation(); selectAllInCategory(cat); }} className="text-[10px] font-semibold text-indigo-500 hover:text-indigo-700 ml-1 cursor-pointer">Select all</span>
                      </button>
                      {isExpanded && (
                        <div className="px-2 pb-2 space-y-0.5">
                          {items.map((s) => {
                            const isSel = selected.has(s.keyword);
                            return (
                              <button key={s.keyword} onClick={() => toggleKeyword(s.keyword)} className={`w-full text-left px-3 py-2 rounded-lg flex items-start gap-2.5 transition-colors ${isSel ? "bg-indigo-100/80 border border-indigo-300" : "bg-white/60 border border-transparent hover:bg-white"}`}>
                                <div className={`w-4 h-4 rounded border flex items-center justify-center shrink-0 mt-0.5 ${isSel ? "bg-indigo-600 border-indigo-600" : "border-slate-300"}`}>
                                  {isSel && <Check className="w-2.5 h-2.5 text-white" />}
                                </div>
                                <div className="flex-1 min-w-0">
                                  <div className="flex items-center gap-1.5">
                                    <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${PRIORITY_DOT[s.priority] ?? "bg-slate-400"}`} />
                                    <span className="text-xs font-semibold text-slate-800 truncate">{s.keyword}</span>
                                    <span className="text-[9px] font-bold uppercase px-1 py-0.5 rounded bg-slate-100 text-slate-500 border border-slate-200 shrink-0">{s.source}</span>
                                  </div>
                                  <p className="text-[10px] text-slate-500 mt-0.5 line-clamp-1">{s.reason}</p>
                                  {(s.currentPosition || s.impressions) && (
                                    <div className="flex items-center gap-3 mt-0.5">
                                      {s.currentPosition && <span className="text-[10px] text-slate-400 tabular-nums">Pos {s.currentPosition}</span>}
                                      {s.impressions && <span className="text-[10px] text-slate-400 tabular-nums">{s.impressions.toLocaleString()} imp</span>}
                                    </div>
                                  )}
                                </div>
                              </button>
                            );
                          })}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}

            {suggestions && selected.size > 0 && (() => {
              const c = countSelected();
              const parts = [c.branded && `${c.branded} branded`, c.nonBranded && `${c.nonBranded} non-branded`, c.striking && `${c.striking} striking distance`, c.local && `${c.local} local`, c.spanish && `${c.spanish} Spanish`].filter(Boolean);
              return (
                <div className="px-4 py-2.5 border-t border-indigo-200 bg-indigo-50/50">
                  <p className="text-[10px] text-indigo-700 font-semibold">Adding {c.total} keyword{c.total !== 1 ? "s" : ""}: {parts.join(", ")}</p>
                </div>
              );
            })()}
          </div>

          {/* Manual keyword entry */}
          <div>
            <label className="block text-[11px] font-semibold text-slate-600 mb-1">Keywords (one per line)</label>
            <textarea rows={5} value={text} onChange={(e) => setText(e.target.value)} placeholder={"modern heart and vascular\nsymptoms of poor circulation\nvascular surgeon near me"} className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500/40 focus:border-brand-500 font-mono" />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-[11px] font-semibold text-slate-600 mb-1">Location</label>
              <select value={location} onChange={(e) => setLocation(e.target.value)} className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg bg-white">
                {COUNTRIES.map((c) => <option key={c} value={c}>{c}</option>)}
                <option value="Custom">Custom…</option>
              </select>
              {location === "Custom" && <input type="text" value={customLocation} onChange={(e) => setCustomLocation(e.target.value)} placeholder="e.g. Houston, TX" className="w-full mt-1.5 px-3 py-2 text-sm border border-slate-200 rounded-lg" />}
            </div>
            <div>
              <label className="block text-[11px] font-semibold text-slate-600 mb-1">Device</label>
              <div className="flex bg-slate-100 rounded-lg p-0.5">
                {(["desktop", "mobile"] as const).map((d) => (
                  <button key={d} onClick={() => setDevice(d)} className={`flex-1 py-2 rounded-md text-xs font-semibold capitalize transition-colors ${device === d ? "bg-white text-slate-900 shadow-sm" : "text-slate-500"}`}>{d}</button>
                ))}
              </div>
            </div>
          </div>
          <div>
            <label className="block text-[11px] font-semibold text-slate-600 mb-1">Target URL (optional)</label>
            <input type="text" value={targetUrl} onChange={(e) => setTargetUrl(e.target.value)} placeholder="/services/cardiology" className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg" />
          </div>
          <div>
            <label className="block text-[11px] font-semibold text-slate-600 mb-1">Tags (comma-separated)</label>
            <input type="text" value={tags} onChange={(e) => setTags(e.target.value)} placeholder="branded, service, location" className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg" />
          </div>
          {error && <p className="text-xs text-red-600">{error}</p>}
        </div>

        <div className="flex items-center justify-end gap-2 border-t border-slate-200 px-5 py-3 bg-slate-50 shrink-0">
          <button onClick={onClose} className="px-4 py-2 text-xs font-semibold text-slate-600">Cancel</button>
          <button onClick={submit} disabled={loading || keywords.length === 0} className="flex items-center gap-1.5 px-4 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700 disabled:opacity-60">
            {loading ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Plus className="w-3.5 h-3.5" />}
            Add {keywords.length} Keyword{keywords.length !== 1 ? "s" : ""}
          </button>
        </div>
      </div>
    </div>
  );
}
