"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import {
  Search, FileText, Link2, Map as MapIcon, AlertTriangle,
  ChevronDown, ChevronRight, Check, X as XIcon, ArrowUpDown, ArrowUp, ArrowDown,
} from "lucide-react";
import { SummaryCard, CardShell, KpiRowSkeleton, TableSkeleton } from "./_shared";

interface PageDiscovery { url: string; firstSeen: string; lastSeen: string; hasTitle: boolean; hasMeta: boolean; hasCanonical: boolean; hasH1: boolean; isNew: boolean; status: number; visits: number }
interface SeoSnapshot { url: string; title: string | null; metaDescription: string | null; canonical: string | null; h1Count: number | null; hasSchema: boolean | null; schemaTypes: string[] | null; noindexed: boolean | null; mixedContent: boolean | null; detectedAt: string; recentlyChanged: boolean }
interface NavLink { href: string; anchorText?: string; section?: string }
interface LinkRow { url: string; outbound: number; inbound: number; isOrphan: boolean; isInNav: boolean }

interface SeoData {
  totalPages: number;
  newPages: number;
  pageDiscovery: PageDiscovery[];
  seoSnapshots: SeoSnapshot[];
  navStructure: { links: NavLink[]; capturedAt: string } | null;
  internalLinks: LinkRow[];
}

export interface SeoMonitorTabProps { brandId: string }

type SortKey = "url" | "firstSeen" | "visits";
type SortDir = "asc" | "desc";

const PAGE_SIZE = 25;

export function SeoMonitorTab({ brandId }: SeoMonitorTabProps) {
  const [data, setData] = useState<SeoData | null>(null);
  const [loading, setLoading] = useState(true);

  // Page Discovery controls
  const [query, setQuery] = useState("");
  const [sortKey, setSortKey] = useState<SortKey>("visits");
  const [sortDir, setSortDir] = useState<SortDir>("desc");
  const [discoveryPage, setDiscoveryPage] = useState(1);

  // SEO snapshots
  const [expandedRow, setExpandedRow] = useState<string | null>(null);

  // Internal links
  const [orphansOnly, setOrphansOnly] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    const res = await fetch(`/api/site-tag/analytics/seo?brandId=${brandId}`);
    if (res.ok) setData(await res.json());
    setLoading(false);
  }, [brandId]);

  useEffect(() => { load(); }, [load]);

  // Filter + sort page discovery
  const filteredPages = useMemo(() => {
    if (!data) return [];
    const q = query.toLowerCase();
    const filtered = q ? data.pageDiscovery.filter((p) => p.url.toLowerCase().includes(q)) : data.pageDiscovery;
    const sorted = [...filtered].sort((a, b) => {
      let cmp = 0;
      if (sortKey === "url") cmp = a.url.localeCompare(b.url);
      else if (sortKey === "firstSeen") cmp = new Date(a.firstSeen).getTime() - new Date(b.firstSeen).getTime();
      else if (sortKey === "visits") cmp = a.visits - b.visits;
      return sortDir === "asc" ? cmp : -cmp;
    });
    return sorted;
  }, [data, query, sortKey, sortDir]);

  const pageCount = Math.max(1, Math.ceil(filteredPages.length / PAGE_SIZE));
  const pagedPages = filteredPages.slice((discoveryPage - 1) * PAGE_SIZE, discoveryPage * PAGE_SIZE);

  // Reset page 1 when the filter or sort changes
  useEffect(() => { setDiscoveryPage(1); }, [query, sortKey, sortDir]);

  // Filter internal links (orphans only)
  const filteredLinks = useMemo(() => {
    if (!data) return [];
    const sorted = [...data.internalLinks].sort((a, b) => (a.isOrphan === b.isOrphan ? a.inbound - b.inbound : a.isOrphan ? -1 : 1));
    return orphansOnly ? sorted.filter((l) => l.isOrphan) : sorted;
  }, [data, orphansOnly]);

  if (loading) {
    return (
      <div className="space-y-6">
        <KpiRowSkeleton />
        <TableSkeleton rows={8} cols={7} />
        <TableSkeleton rows={4} cols={3} />
      </div>
    );
  }

  if (!data || data.totalPages === 0) {
    return (
      <div className="bg-white rounded-xl border border-slate-200 p-12 text-center">
        <Search className="w-10 h-10 text-slate-200 mx-auto mb-3" />
        <h2 className="text-lg font-bold text-slate-900 mb-1">No SEO Data Yet</h2>
        <p className="text-sm text-slate-500 max-w-sm mx-auto">
          This data will appear once the Site Tag discovers pages on your site and collects SEO metadata.
        </p>
      </div>
    );
  }

  const orphanCount = data.internalLinks.filter((l) => l.isOrphan).length;

  function toggleSort(key: SortKey) {
    if (sortKey === key) setSortDir(sortDir === "asc" ? "desc" : "asc");
    else { setSortKey(key); setSortDir("desc"); }
  }

  function sortIcon(key: SortKey) {
    if (sortKey !== key) return <ArrowUpDown className="w-3 h-3 text-slate-300" />;
    return sortDir === "asc" ? <ArrowUp className="w-3 h-3 text-brand-600" /> : <ArrowDown className="w-3 h-3 text-brand-600" />;
  }

  return (
    <div className="space-y-6">
      {/* Summary cards */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        <SummaryCard
          label="Pages Discovered"
          value={data.totalPages.toLocaleString()}
          icon={FileText}
          iconColor="text-slate-400"
        />
        <SummaryCard
          label="New This Week"
          value={data.newPages.toLocaleString()}
          icon={FileText}
          iconColor="text-emerald-500"
          tone={data.newPages > 0 ? "good" : "default"}
        />
        <SummaryCard
          label="SEO Snapshots"
          value={data.seoSnapshots.length.toLocaleString()}
          icon={Search}
          iconColor="text-blue-500"
        />
        <SummaryCard
          label="Orphan Pages"
          value={orphanCount.toLocaleString()}
          icon={AlertTriangle}
          iconColor={orphanCount > 0 ? "text-red-500" : "text-slate-400"}
          tone={orphanCount > 0 ? "bad" : "default"}
        />
      </div>

      {/* Page Discovery with search + pagination + sort */}
      {data.pageDiscovery.length > 0 && (
        <CardShell
          title="Page Discovery"
          icon={FileText}
          right={<span className="text-[10px] font-semibold text-slate-400 uppercase tracking-widest">{filteredPages.length} of {data.totalPages}</span>}
        >
          {/* Toolbar */}
          <div className="px-5 py-3 border-b border-slate-100 bg-slate-50/50 flex items-center gap-3">
            <div className="relative flex-1 max-w-sm">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-slate-400 pointer-events-none" />
              <input
                type="text"
                placeholder="Filter pages..."
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                className="w-full pl-9 pr-3 py-1.5 text-xs bg-white border border-slate-200 rounded-lg focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100"
              />
            </div>
            <div className="ml-auto flex items-center gap-2 text-[11px] text-slate-500">
              <span>Page {discoveryPage} of {pageCount}</span>
              <button
                onClick={() => setDiscoveryPage((p) => Math.max(1, p - 1))}
                disabled={discoveryPage === 1}
                className="px-2 py-1 rounded-md bg-white border border-slate-200 text-slate-600 hover:bg-slate-50 disabled:opacity-40 disabled:cursor-not-allowed"
              >
                Prev
              </button>
              <button
                onClick={() => setDiscoveryPage((p) => Math.min(pageCount, p + 1))}
                disabled={discoveryPage >= pageCount}
                className="px-2 py-1 rounded-md bg-white border border-slate-200 text-slate-600 hover:bg-slate-50 disabled:opacity-40 disabled:cursor-not-allowed"
              >
                Next
              </button>
            </div>
          </div>

          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="text-left text-[11px] font-semibold uppercase tracking-wider text-slate-400 border-b border-slate-100 bg-slate-50">
                  <th className="px-5 py-2.5">
                    <button onClick={() => toggleSort("url")} className="inline-flex items-center gap-1 hover:text-slate-600">
                      URL {sortIcon("url")}
                    </button>
                  </th>
                  <th className="px-5 py-2.5">
                    <button onClick={() => toggleSort("firstSeen")} className="inline-flex items-center gap-1 hover:text-slate-600">
                      First Seen {sortIcon("firstSeen")}
                    </button>
                  </th>
                  <th className="px-5 py-2.5 text-center">Title</th>
                  <th className="px-5 py-2.5 text-center">Meta</th>
                  <th className="px-5 py-2.5 text-center">Canonical</th>
                  <th className="px-5 py-2.5 text-center">H1</th>
                  <th className="px-5 py-2.5 text-right">
                    <button onClick={() => toggleSort("visits")} className="inline-flex items-center gap-1 hover:text-slate-600">
                      Visits {sortIcon("visits")}
                    </button>
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {pagedPages.length === 0 && (
                  <tr>
                    <td colSpan={7} className="px-5 py-8 text-center text-xs text-slate-400">
                      No pages match &ldquo;{query}&rdquo;
                    </td>
                  </tr>
                )}
                {pagedPages.map((p) => (
                  <tr key={p.url} className="hover:bg-slate-50 transition-colors">
                    <td className="px-5 py-2.5 font-mono text-xs text-brand-600 max-w-[360px] truncate" title={p.url}>
                      {p.isNew && (
                        <span className="inline-block mr-1.5 text-[9px] font-bold bg-emerald-50 text-emerald-700 border border-emerald-200 rounded-full px-1.5 py-0.5">New</span>
                      )}
                      {p.url}
                    </td>
                    <td className="px-5 py-2.5 text-xs text-slate-500 tabular-nums whitespace-nowrap">
                      {new Date(p.firstSeen).toLocaleDateString(undefined, { month: "short", day: "numeric" })}
                    </td>
                    <td className="px-5 py-2.5 text-center">{p.hasTitle ? <CheckIcon /> : <CrossIcon />}</td>
                    <td className="px-5 py-2.5 text-center">{p.hasMeta ? <CheckIcon /> : <CrossIcon />}</td>
                    <td className="px-5 py-2.5 text-center">{p.hasCanonical ? <CheckIcon /> : <CrossIcon />}</td>
                    <td className="px-5 py-2.5 text-center">{p.hasH1 ? <CheckIcon /> : <CrossIcon />}</td>
                    <td className="px-5 py-2.5 text-right text-xs font-bold text-slate-900 tabular-nums">{p.visits.toLocaleString()}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </CardShell>
      )}

      {/* SEO Snapshots — expandable rows */}
      {data.seoSnapshots.length > 0 && (
        <CardShell
          title="SEO Metadata Snapshots"
          icon={Search}
          right={<span className="text-[10px] font-semibold text-slate-400 uppercase tracking-widest">{data.seoSnapshots.length}</span>}
        >
          <div className="divide-y divide-slate-100 max-h-96 overflow-y-auto">
            {data.seoSnapshots.slice(0, 30).map((s) => (
              <div key={s.url}>
                <button
                  onClick={() => setExpandedRow(expandedRow === s.url ? null : s.url)}
                  className="w-full px-5 py-3 flex items-center gap-3 hover:bg-slate-50 text-left transition-colors"
                >
                  {expandedRow === s.url
                    ? <ChevronDown className="w-3 h-3 text-slate-400 shrink-0" />
                    : <ChevronRight className="w-3 h-3 text-slate-400 shrink-0" />}
                  <span className="font-mono text-xs text-brand-600 flex-1 truncate" title={s.url}>{s.url}</span>
                  {s.recentlyChanged && (
                    <span className="text-[9px] font-bold bg-amber-50 text-amber-700 border border-amber-200 rounded-full px-1.5 py-0.5">Changed</span>
                  )}
                  {s.noindexed && (
                    <span className="text-[9px] font-bold bg-red-50 text-red-700 border border-red-200 rounded-full px-1.5 py-0.5">Noindex</span>
                  )}
                  {s.hasSchema && (
                    <span className="text-[9px] font-bold bg-green-50 text-green-700 border border-green-200 rounded-full px-1.5 py-0.5">Schema</span>
                  )}
                </button>
                {expandedRow === s.url && (
                  <div className="px-10 py-3 bg-slate-50 grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-1 text-xs">
                    <div><span className="text-slate-400">Title:</span> <span className="text-slate-700">{s.title || "\u2014"}</span></div>
                    <div className="truncate" title={s.canonical ?? ""}><span className="text-slate-400">Canonical:</span> <span className="font-mono text-slate-700">{s.canonical || "\u2014"}</span></div>
                    <div className="col-span-full"><span className="text-slate-400">Meta:</span> <span className="text-slate-700">{s.metaDescription || "\u2014"}</span></div>
                    <div><span className="text-slate-400">H1 Count:</span> <span className="text-slate-700">{s.h1Count ?? "\u2014"}</span></div>
                    <div><span className="text-slate-400">Schema Types:</span> <span className="text-slate-700">{s.schemaTypes?.join(", ") || "\u2014"}</span></div>
                    {s.mixedContent && <div className="col-span-full text-red-600 font-semibold">Mixed content detected</div>}
                  </div>
                )}
              </div>
            ))}
          </div>
        </CardShell>
      )}

      {/* Navigation Structure — tree view */}
      {data.navStructure && (
        <CardShell
          title="Navigation Structure"
          icon={MapIcon}
          right={<span className="text-[10px] font-semibold text-slate-400 uppercase tracking-widest">Captured {new Date(data.navStructure.capturedAt).toLocaleDateString()}</span>}
        >
          <NavTree links={data.navStructure.links as NavLink[]} />
        </CardShell>
      )}

      {/* Internal Links with orphan filter */}
      {data.internalLinks.length > 0 && (
        <CardShell
          title="Internal Links"
          icon={Link2}
          right={
            <label className="flex items-center gap-1.5 text-[10px] font-semibold text-slate-500 cursor-pointer">
              <input
                type="checkbox"
                checked={orphansOnly}
                onChange={(e) => setOrphansOnly(e.target.checked)}
                className="w-3 h-3 rounded border-slate-300 text-brand-600 focus:ring-brand-500"
              />
              Show orphans only
            </label>
          }
        >
          <div className="overflow-x-auto max-h-96 overflow-y-auto">
            <table className="w-full text-sm">
              <thead className="sticky top-0">
                <tr className="text-left text-[11px] font-semibold uppercase tracking-wider text-slate-400 border-b border-slate-100 bg-slate-50">
                  <th className="px-5 py-2.5">Page</th>
                  <th className="px-5 py-2.5 text-right">Outbound</th>
                  <th className="px-5 py-2.5 text-right">Inbound</th>
                  <th className="px-5 py-2.5 text-right">Status</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {filteredLinks.length === 0 && (
                  <tr>
                    <td colSpan={4} className="px-5 py-8 text-center text-xs text-slate-400">
                      No orphan pages — every page has at least one inbound link.
                    </td>
                  </tr>
                )}
                {filteredLinks.map((l) => (
                  <tr key={l.url} className={`transition-colors ${l.isOrphan ? "bg-red-50/40 hover:bg-red-50/60" : "hover:bg-slate-50"}`}>
                    <td className="px-5 py-2.5 font-mono text-xs text-brand-600 max-w-[360px] truncate" title={l.url}>{l.url}</td>
                    <td className="px-5 py-2.5 text-right text-xs tabular-nums text-slate-600">{l.outbound}</td>
                    <td className="px-5 py-2.5 text-right text-xs tabular-nums text-slate-600">{l.inbound}</td>
                    <td className="px-5 py-2.5 text-right">
                      {l.isOrphan ? (
                        <span className="inline-flex items-center gap-0.5 text-[9px] font-bold text-red-600">
                          <AlertTriangle className="w-3 h-3" /> Orphan
                        </span>
                      ) : l.isInNav ? (
                        <span className="text-[9px] font-bold text-green-600">In Nav</span>
                      ) : (
                        <span className="text-[9px] text-slate-400">Linked</span>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </CardShell>
      )}
    </div>
  );
}

// ─── Nav tree ───────────────────────────────────────────────────────────────

function NavTree({ links }: { links: NavLink[] }) {
  // Group by top-level path segment
  const groups = useMemo<Array<[string, NavLink[]]>>(() => {
    const map = new Map<string, NavLink[]>();
    for (const l of links) {
      let seg = "/";
      try {
        const url = new URL(l.href, "https://x");
        const parts = url.pathname.split("/").filter(Boolean);
        seg = parts[0] ? `/${parts[0]}` : "/";
      } catch { seg = "/"; }
      const bucket = map.get(seg) ?? [];
      bucket.push(l);
      map.set(seg, bucket);
    }
    return Array.from(map.entries()).sort((a, b) => a[0].localeCompare(b[0]));
  }, [links]);

  const [expanded, setExpanded] = useState<Set<string>>(new Set(groups.slice(0, 3).map(([k]) => k)));

  function toggle(k: string) {
    const next = new Set(expanded);
    if (next.has(k)) next.delete(k); else next.add(k);
    setExpanded(next);
  }

  return (
    <div className="max-h-80 overflow-y-auto">
      {groups.map(([seg, items]) => {
        const isOpen = expanded.has(seg);
        return (
          <div key={seg}>
            <button
              onClick={() => toggle(seg)}
              className="w-full flex items-center gap-2 px-5 py-2 hover:bg-slate-50 text-left"
            >
              {isOpen ? <ChevronDown className="w-3 h-3 text-slate-400" /> : <ChevronRight className="w-3 h-3 text-slate-400" />}
              <span className="font-mono text-xs font-semibold text-slate-800">{seg}</span>
              <span className="text-[10px] text-slate-400">{items.length}</span>
            </button>
            {isOpen && (
              <div className="pl-10 pr-5 py-1 space-y-0.5 border-l border-slate-100 ml-4">
                {items.slice(0, 30).map((l, i) => (
                  <div key={`${seg}-${i}`} className="flex items-center gap-2 py-1 text-xs">
                    <span className="font-mono text-brand-600 truncate flex-1" title={l.href}>{l.href}</span>
                    {l.anchorText && (
                      <span className="text-slate-400 truncate max-w-[180px]" title={l.anchorText}>{l.anchorText}</span>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ─── Tiny icons ─────────────────────────────────────────────────────────────

function CheckIcon() {
  return <Check className="w-3.5 h-3.5 text-emerald-500 mx-auto" />;
}
function CrossIcon() {
  return <XIcon className="w-3.5 h-3.5 text-slate-300 mx-auto" />;
}
