"use client";

/**
 * Page Launch Tracker — Command Center for Page Lifecycle Intelligence
 * ────────────────────────────────────────────────────────────────────
 * Shows every page the Site Tag has ever detected on the brand's site
 * alongside its lifecycle (first seen, status changes, nav additions),
 * GSC-backed performance (clicks, impressions, CTR, position), and
 * inbound redirects. A detail drawer shows a full timeline + daily
 * performance chart + comparison deltas for the selected page.
 *
 * Data source: /api/pages/tracker, /api/pages/[pageId]/history,
 *              /api/pages/[pageId]/compare
 */

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  Globe, Clock, AlertTriangle, ArrowUpRight, Search, X, Eye,
  TrendingUp, TrendingDown, Activity, Compass, FileWarning,
  ArrowRight, Navigation, Tag, RefreshCw, Loader2, Map as MapIcon,
} from "lucide-react";
import { useBrand } from "@/context/brand-context";
import {
  ResponsiveContainer, LineChart, Line, XAxis, YAxis, Tooltip as RTooltip,
  CartesianGrid,
} from "recharts";
import FeatureGate from "@/components/plan/feature-gate";

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

interface PageRow {
  id: string;
  url: string;
  fullUrl: string;
  title: string | null;
  currentStatus: number;
  firstSeenAt: string;
  lastSeenAt: string;
  isInNav: boolean;
  addedToNavAt: string | null;
  totalClicks: number;
  totalImpressions: number;
  currentCtr: number;
  currentPosition: number;
  totalVisits: number;
  redirectsInCount: number;
  statusChangeCount: number;
  daysLive: number;
  // Three independent launch-date signals joined on the backend from
  // the sitemap cache + GSC earliest-date aggregation + PageRecord.
  // Any may be null when that source hasn't observed the page yet.
  sitemapLastmod: string | null;
  gscFirstSeenAt: string | null;
  tagFirstSeenAt: string;
  /** Earliest of the three — true "launch date" for daysLive. */
  launchDate: string;
  launchSource: "sitemap" | "gsc" | "tag";
}

interface TrackerResponse {
  summary: {
    total: number;
    live: number;
    redirects: number;
    notFound: number;
    serverError: number;
    newThisMonth: number;
    inNav: number;
  };
  sitemapCache: { crawledAt: string; count: number } | null;
  pages: PageRow[];
  recentlyDetected: Array<{
    id: string; url: string; title: string | null;
    firstSeenAt: string; currentStatus: number;
    isInNav: boolean; addedToNavAt: string | null;
  }>;
  recent404s: Array<{
    pageId: string; url: string; title: string | null;
    detectedAt: string; fromStatus: number;
    lostClicks: number; lostImpressions: number;
    inboundLinkCount: number;
  }>;
}

type StatusFilter = "all" | "live" | "redirect" | "notfound" | "servererror";
type NavFilter = "all" | "in" | "out";
type SortKey = "firstSeen" | "lastSeen" | "clicks" | "impressions" | "position" | "url";

// ─── Helpers ────────────────────────────────────────────────────────────────

function statusColor(status: number): { bg: string; text: string; dot: string; label: string } {
  if (status >= 200 && status < 300) return { bg: "bg-emerald-50", text: "text-emerald-700", dot: "bg-emerald-500", label: `${status}` };
  if (status >= 300 && status < 400) return { bg: "bg-amber-50",   text: "text-amber-700",   dot: "bg-amber-500",   label: `${status}` };
  if (status === 404)                return { bg: "bg-red-50",     text: "text-red-700",     dot: "bg-red-500",     label: "404" };
  if (status >= 500)                 return { bg: "bg-slate-100",  text: "text-slate-700",   dot: "bg-slate-600",   label: `${status}` };
  return { bg: "bg-slate-50", text: "text-slate-600", dot: "bg-slate-400", label: `${status}` };
}

function formatDate(s: string): string {
  try { return new Date(s).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); }
  catch { return s; }
}

function formatNumber(n: number): string {
  if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + "M";
  if (n >= 1_000) return (n / 1_000).toFixed(1) + "K";
  return String(n);
}

function relativeTime(s: string): string {
  try {
    const ms = Date.now() - new Date(s).getTime();
    const days = Math.floor(ms / (1000 * 60 * 60 * 24));
    if (days === 0) return "today";
    if (days === 1) return "yesterday";
    if (days < 30) return `${days}d ago`;
    if (days < 365) return `${Math.floor(days / 30)}mo ago`;
    return `${Math.floor(days / 365)}y ago`;
  } catch { return ""; }
}

// ─── Page component ─────────────────────────────────────────────────────────

// Page Launch Tracker is a Professional+ feature. FeatureGate wrapper
// catches direct navigations that bypass the sidebar's locked-click handler.
export default function PageLaunchTrackerPageGated() {
  return (
    <FeatureGate feature="page_launch_tracker">
      <PageLaunchTrackerPage />
    </FeatureGate>
  );
}

function PageLaunchTrackerPage() {
  const { brand } = useBrand();
  const [data, setData] = useState<TrackerResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState<string | null>(null);

  const [statusFilter, setStatusFilter] = useState<StatusFilter>("all");
  const [navFilter, setNavFilter] = useState<NavFilter>("all");
  const [sort, setSort] = useState<SortKey>("lastSeen");
  const [dir, setDir] = useState<"asc" | "desc">("desc");
  const [search, setSearch] = useState("");

  const [selectedPageId, setSelectedPageId] = useState<string | null>(null);
  const [crawlingSitemap, setCrawlingSitemap] = useState(false);
  const [sitemapError, setSitemapError] = useState<string | null>(null);

  const load = useCallback(async () => {
    if (!brand.id) return;
    setLoading(true);
    setErr(null);
    try {
      const params = new URLSearchParams({
        brandId: brand.id,
        status: statusFilter,
        nav: navFilter,
        sort,
        dir,
      });
      const res = await fetch(`/api/pages/tracker?${params.toString()}`);
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as TrackerResponse;
      setData(json);
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Failed to load");
    } finally {
      setLoading(false);
    }
  }, [brand.id, statusFilter, navFilter, sort, dir]);

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

  // Kick a sitemap crawl on demand. The tracker API returns sitemap-
  // derived launch dates whenever the cache has content — this button
  // forces a refresh so users who just installed a brand or published
  // new pages can populate the sitemap column without waiting for the
  // nightly cron.
  async function refreshSitemap() {
    if (!brand.id) return;
    setCrawlingSitemap(true); setSitemapError(null);
    try {
      const res = await fetch("/api/pages/sitemap-crawl", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId: brand.id }),
      });
      if (!res.ok) {
        const d = await res.json().catch(() => ({}));
        throw new Error(d.error || "Sitemap crawl failed");
      }
      // Re-load the tracker so the new sitemap dates get joined in.
      await load();
    } catch (e) {
      setSitemapError(e instanceof Error ? e.message : "Sitemap crawl failed");
    } finally {
      setCrawlingSitemap(false);
    }
  }

  const filteredPages = useMemo(() => {
    if (!data) return [];
    const q = search.trim().toLowerCase();
    if (!q) return data.pages;
    return data.pages.filter(p =>
      p.url.toLowerCase().includes(q) ||
      (p.title ? p.title.toLowerCase().includes(q) : false),
    );
  }, [data, search]);

  const summary = data?.summary;

  return (
    <div className="space-y-6 pb-16">
      {/* Header */}
      <div className="flex items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-slate-900 flex items-center gap-2">
            <Compass className="w-6 h-6 text-brand-600" />
            Page Launch Tracker
          </h1>
          <p className="text-slate-500 text-sm mt-1">
            Real-time page lifecycle intelligence — every page, every status change, every click.
          </p>
        </div>
        <div className="flex items-center gap-2">
          {brand.domain && (
            <div className="text-xs text-slate-500 bg-slate-50 px-3 py-2 rounded-lg border border-slate-200">
              Tracking <span className="font-semibold text-slate-700">{brand.domain}</span>
            </div>
          )}
          {brand.domain && (
            <button
              onClick={refreshSitemap}
              disabled={crawlingSitemap}
              title={
                data?.sitemapCache
                  ? `Sitemap cached ${relativeTime(data.sitemapCache.crawledAt)} · ${formatNumber(data.sitemapCache.count)} URLs`
                  : "No sitemap cached yet — click to crawl"
              }
              className="inline-flex items-center gap-1.5 text-xs px-3 py-2 rounded-lg border border-slate-200 bg-white hover:bg-slate-50 text-slate-700 disabled:opacity-60"
            >
              {crawlingSitemap
                ? <Loader2 className="w-3.5 h-3.5 animate-spin" />
                : <RefreshCw className="w-3.5 h-3.5" />}
              <span className="font-semibold">
                {crawlingSitemap ? "Crawling sitemap…" : "Refresh sitemap"}
              </span>
              {data?.sitemapCache && !crawlingSitemap && (
                <span className="text-slate-400 font-normal">
                  ({formatNumber(data.sitemapCache.count)} URLs)
                </span>
              )}
            </button>
          )}
        </div>
      </div>
      {sitemapError && (
        <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 flex items-center gap-2">
          <AlertTriangle className="w-3.5 h-3.5" /> Sitemap crawl failed: {sitemapError}
        </div>
      )}

      {/* Summary cards */}
      <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3">
        <SummaryCard icon={<Globe className="w-4 h-4" />} label="Total Pages" value={summary?.total ?? 0} color="slate" />
        <SummaryCard icon={<Tag className="w-4 h-4" />}     label="New This Month" value={summary?.newThisMonth ?? 0} color="indigo" />
        <SummaryCard icon={<Activity className="w-4 h-4" />} label="Live (200)" value={summary?.live ?? 0} color="emerald" />
        <SummaryCard icon={<ArrowRight className="w-4 h-4" />} label="Redirected" value={summary?.redirects ?? 0} color="amber" />
        <SummaryCard icon={<FileWarning className="w-4 h-4" />} label="404 Pages" value={summary?.notFound ?? 0} color="red" />
        <SummaryCard icon={<Navigation className="w-4 h-4" />} label="In Navigation" value={summary?.inNav ?? 0} color="sky" />
      </div>

      {/* Alert rows */}
      {data && (data.recentlyDetected.length > 0 || data.recent404s.length > 0) && (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
          {data.recentlyDetected.length > 0 && (
            <div className="rounded-xl border border-indigo-200 bg-gradient-to-br from-indigo-50 to-white p-4">
              <div className="flex items-center gap-2 mb-3">
                <Tag className="w-4 h-4 text-indigo-600" />
                <h2 className="font-bold text-sm text-slate-900">Recently Detected</h2>
                <span className="text-[10px] font-semibold bg-indigo-100 text-indigo-700 rounded-full px-2 py-0.5">
                  {data.recentlyDetected.length}
                </span>
              </div>
              <div className="space-y-1.5">
                {data.recentlyDetected.slice(0, 5).map(p => (
                  <button
                    key={p.id}
                    onClick={() => setSelectedPageId(p.id)}
                    className="w-full text-left flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white transition-colors"
                  >
                    <span className="text-xs font-mono text-slate-700 truncate flex-1">{p.url}</span>
                    {p.isInNav && (
                      <span className="text-[9px] font-bold uppercase bg-sky-100 text-sky-700 px-1.5 py-0.5 rounded">In nav</span>
                    )}
                    <span className="text-[10px] text-slate-500">{relativeTime(p.firstSeenAt)}</span>
                  </button>
                ))}
              </div>
            </div>
          )}
          {data.recent404s.length > 0 && (
            <div className="rounded-xl border border-red-200 bg-gradient-to-br from-red-50 to-white p-4">
              <div className="flex items-center gap-2 mb-3">
                <AlertTriangle className="w-4 h-4 text-red-600" />
                <h2 className="font-bold text-sm text-slate-900">Recent 404 Alerts</h2>
                <span className="text-[10px] font-semibold bg-red-100 text-red-700 rounded-full px-2 py-0.5">
                  {data.recent404s.length}
                </span>
              </div>
              <div className="space-y-1.5">
                {data.recent404s.slice(0, 5).map(p => (
                  <button
                    key={p.pageId + p.detectedAt}
                    onClick={() => setSelectedPageId(p.pageId)}
                    className="w-full text-left flex items-center gap-2 px-2 py-1.5 rounded hover:bg-white transition-colors"
                  >
                    <span className="text-xs font-mono text-slate-700 truncate flex-1">{p.url}</span>
                    {p.lostClicks > 0 && (
                      <span className="text-[10px] text-red-600 font-semibold">-{formatNumber(p.lostClicks)} clicks</span>
                    )}
                    <span className="text-[10px] text-slate-500">{relativeTime(p.detectedAt)}</span>
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
      )}

      {/* Filter bar */}
      <div className="bg-white border border-slate-200 rounded-xl p-3 flex flex-wrap items-center gap-2">
        <div className="relative flex-1 min-w-[200px]">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-slate-400" />
          <input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search pages..."
            className="w-full pl-9 pr-3 py-2 text-sm bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent"
          />
        </div>
        <FilterDropdown
          label="Status"
          value={statusFilter}
          onChange={(v) => setStatusFilter(v as StatusFilter)}
          options={[
            { value: "all", label: "All statuses" },
            { value: "live", label: "Live (200)" },
            { value: "redirect", label: "Redirected (3xx)" },
            { value: "notfound", label: "Not found (404)" },
            { value: "servererror", label: "Server error (5xx)" },
          ]}
        />
        <FilterDropdown
          label="Nav"
          value={navFilter}
          onChange={(v) => setNavFilter(v as NavFilter)}
          options={[
            { value: "all", label: "All pages" },
            { value: "in", label: "In navigation" },
            { value: "out", label: "Not in navigation" },
          ]}
        />
        <FilterDropdown
          label="Sort"
          value={sort}
          onChange={(v) => setSort(v as SortKey)}
          options={[
            { value: "lastSeen", label: "Last seen" },
            { value: "firstSeen", label: "First seen" },
            { value: "clicks", label: "Clicks" },
            { value: "impressions", label: "Impressions" },
            { value: "position", label: "Position" },
            { value: "url", label: "URL" },
          ]}
        />
        <button
          onClick={() => setDir(d => (d === "asc" ? "desc" : "asc"))}
          className="px-2.5 py-1.5 rounded-lg border border-slate-200 text-xs font-semibold text-slate-600 hover:bg-slate-50"
          title={dir === "asc" ? "Ascending" : "Descending"}
        >
          {dir === "asc" ? "↑" : "↓"}
        </button>
      </div>

      {/* Main table */}
      <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
        {loading && !data ? (
          <div className="p-12 text-center text-slate-500 text-sm">Loading pages…</div>
        ) : err ? (
          <div className="p-8 text-center text-red-600 text-sm">{err}</div>
        ) : filteredPages.length === 0 ? (
          <EmptyState />
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-slate-50 border-b border-slate-200">
                <tr className="text-[10px] font-bold text-slate-500 uppercase tracking-wider">
                  <th className="text-left px-4 py-3">URL</th>
                  <th className="text-left px-3 py-3">Status</th>
                  <th className="text-right px-3 py-3" title="Earliest of sitemap lastmod / GSC first seen / Site Tag first seen. Hover a row for all three.">Launch Date</th>
                  <th className="text-right px-3 py-3" title="Days since the earliest known launch signal">Days Live</th>
                  <th className="text-right px-3 py-3">Clicks</th>
                  <th className="text-right px-3 py-3">Impr.</th>
                  <th className="text-right px-3 py-3">CTR</th>
                  <th className="text-right px-3 py-3">Pos.</th>
                  <th className="text-right px-3 py-3">↪ In</th>
                  <th className="text-right px-3 py-3">Δ</th>
                  <th className="text-right px-4 py-3"></th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {filteredPages.map(p => {
                  const s = statusColor(p.currentStatus);
                  return (
                    <tr key={p.id} className="hover:bg-slate-50/50 transition-colors">
                      <td className="px-4 py-2.5">
                        <div className="flex items-center gap-2 min-w-0">
                          <span className={`w-1.5 h-1.5 rounded-full ${s.dot} shrink-0`} />
                          <div className="min-w-0">
                            <div className="text-xs font-mono text-slate-700 truncate max-w-[280px]">{p.url}</div>
                            {p.title && <div className="text-[10px] text-slate-400 truncate max-w-[280px]">{p.title}</div>}
                          </div>
                          {p.isInNav && (
                            <span className="text-[8px] font-bold uppercase bg-sky-100 text-sky-700 px-1 py-0.5 rounded shrink-0">nav</span>
                          )}
                        </div>
                      </td>
                      <td className="px-3 py-2.5">
                        <span className={`text-[10px] font-bold ${s.bg} ${s.text} px-1.5 py-0.5 rounded`}>{s.label}</span>
                      </td>
                      <td className="px-3 py-2.5 text-right"><LaunchDateCell p={p} /></td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{p.daysLive}d</td>
                      <td className="px-3 py-2.5 text-right text-xs font-semibold text-slate-700">{formatNumber(p.totalClicks)}</td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{formatNumber(p.totalImpressions)}</td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{p.currentCtr > 0 ? `${(p.currentCtr * 100).toFixed(1)}%` : "—"}</td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{p.currentPosition > 0 ? p.currentPosition.toFixed(1) : "—"}</td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{p.redirectsInCount || "—"}</td>
                      <td className="px-3 py-2.5 text-right text-xs text-slate-600">{p.statusChangeCount || "—"}</td>
                      <td className="px-4 py-2.5 text-right">
                        <button
                          onClick={() => setSelectedPageId(p.id)}
                          className="inline-flex items-center gap-1 text-[10px] font-bold text-brand-700 hover:text-brand-900"
                        >
                          View <ArrowUpRight className="w-3 h-3" />
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      {/* Detail drawer */}
      {selectedPageId && (
        <PageDetailDrawer
          pageId={selectedPageId}
          onClose={() => setSelectedPageId(null)}
        />
      )}
    </div>
  );
}

// ─── Subcomponents ──────────────────────────────────────────────────────────

/** Inline cell renderer for the Launch Date column. Shows the earliest
 *  launch signal with a tiny source chip (sitemap / GSC / tag) and a
 *  full tooltip listing all three sources so users can audit where the
 *  date came from. */
function LaunchDateCell({ p }: { p: PageRow }) {
  const sourceMeta: Record<PageRow["launchSource"], { label: string; chip: string; icon: React.ReactNode }> = {
    sitemap: { label: "Sitemap lastmod", chip: "bg-indigo-50 text-indigo-700", icon: <MapIcon className="w-2.5 h-2.5" /> },
    gsc:     { label: "GSC first seen",  chip: "bg-emerald-50 text-emerald-700", icon: <Search className="w-2.5 h-2.5" /> },
    tag:     { label: "Tag first seen",  chip: "bg-slate-100 text-slate-600", icon: <Tag className="w-2.5 h-2.5" /> },
  };
  const meta = sourceMeta[p.launchSource];
  const tooltipLines = [
    `Launch date: ${formatDate(p.launchDate)} (from ${meta.label})`,
    p.sitemapLastmod ? `Sitemap lastmod: ${formatDate(p.sitemapLastmod)}` : "Sitemap lastmod: —",
    p.gscFirstSeenAt ? `GSC first seen: ${formatDate(p.gscFirstSeenAt)}` : "GSC first seen: —",
    `Tag first seen: ${formatDate(p.tagFirstSeenAt)}`,
  ].join("\n");
  return (
    <div className="inline-flex items-center gap-1.5" title={tooltipLines}>
      <span className="text-xs text-slate-700">{formatDate(p.launchDate)}</span>
      <span className={`inline-flex items-center gap-0.5 text-[9px] font-bold uppercase tracking-wide px-1 py-0.5 rounded ${meta.chip}`}>
        {meta.icon}
        {p.launchSource}
      </span>
    </div>
  );
}

function SummaryCard({ icon, label, value, color }: {
  icon: React.ReactNode;
  label: string;
  value: number;
  color: "slate" | "indigo" | "emerald" | "amber" | "red" | "sky";
}) {
  const bg = {
    slate: "bg-slate-50 text-slate-600 border-slate-200",
    indigo: "bg-indigo-50 text-indigo-600 border-indigo-200",
    emerald: "bg-emerald-50 text-emerald-600 border-emerald-200",
    amber: "bg-amber-50 text-amber-600 border-amber-200",
    red: "bg-red-50 text-red-600 border-red-200",
    sky: "bg-sky-50 text-sky-600 border-sky-200",
  }[color];
  return (
    <div className={`rounded-xl border ${bg} p-3`}>
      <div className="flex items-center gap-1.5 text-[10px] font-bold uppercase tracking-wider">
        {icon}
        <span>{label}</span>
      </div>
      <div className="text-2xl font-bold text-slate-900 mt-1">{formatNumber(value)}</div>
    </div>
  );
}

function FilterDropdown({ label, value, onChange, options }: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  options: Array<{ value: string; label: string }>;
}) {
  return (
    <div className="flex items-center gap-1.5">
      <span className="text-[10px] font-bold text-slate-500 uppercase">{label}</span>
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="px-2 py-1.5 text-xs bg-white border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 min-w-[120px]"
      >
        {options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
    </div>
  );
}

function EmptyState() {
  return (
    <div className="p-12 text-center">
      <Globe className="w-12 h-12 text-slate-300 mx-auto mb-3" />
      <h3 className="text-sm font-bold text-slate-700">No pages detected yet</h3>
      <p className="text-xs text-slate-500 mt-1 max-w-md mx-auto">
        Install the meSEO Site Tag on your website. Pages will appear here automatically as visitors land on them.
      </p>
      <Link
        href="/site-tag"
        className="inline-flex items-center gap-1 mt-4 text-xs font-bold text-brand-700 hover:text-brand-900"
      >
        Install Site Tag <ArrowUpRight className="w-3 h-3" />
      </Link>
    </div>
  );
}

// ─── Detail drawer ──────────────────────────────────────────────────────────

interface HistoryResponse {
  page: {
    id: string;
    url: string;
    fullUrl: string;
    title: string | null;
    currentStatus: number;
    firstSeenAt: string;
    lastSeenAt: string;
    isInNav: boolean;
    addedToNavAt: string | null;
    totalClicks: number;
    totalImpressions: number;
    currentCtr: number;
    currentPosition: number;
    totalVisits: number;
    metaDescription: string | null;
    h1: string | null;
    canonicalUrl: string | null;
    wordCount: number | null;
    daysLive: number;
  };
  dailyMetrics: Array<{
    date: string;
    clicks: number;
    impressions: number;
    ctr: number;
    avgPosition: number;
  }>;
  redirectsIn: Array<{ id: string; sourceUrl: string; targetUrl: string; statusCode: number; firstSeenAt: string }>;
  redirectsOut: Array<{ id: string; sourceUrl: string; targetUrl: string; statusCode: number; firstSeenAt: string }>;
  timeline: Array<{ at: string; type: string; label: string; status?: number }>;
}

interface CompareResponse {
  current: { clicks: number; impressions: number; ctr: number; avgPosition: number };
  previous: { clicks: number; impressions: number; ctr: number; avgPosition: number };
  deltas: {
    clicks: { absolute: number; relative: number };
    impressions: { absolute: number; relative: number };
    ctr: { absolute: number; relative: number };
    avgPosition: { absolute: number; relative: number };
  };
}

function PageDetailDrawer({ pageId, onClose }: { pageId: string; onClose: () => void }) {
  const [history, setHistory] = useState<HistoryResponse | null>(null);
  const [compare, setCompare] = useState<CompareResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState<string | null>(null);

  useEffect(() => {
    let alive = true;
    setLoading(true);
    setErr(null);
    Promise.all([
      fetch(`/api/pages/${pageId}/history`).then(r => r.ok ? r.json() : Promise.reject(new Error("history failed"))),
      fetch(`/api/pages/${pageId}/compare?range=30d`).then(r => r.ok ? r.json() : Promise.reject(new Error("compare failed"))),
    ]).then(([h, c]) => {
      if (!alive) return;
      setHistory(h);
      setCompare(c);
    }).catch(e => {
      if (!alive) return;
      setErr(e instanceof Error ? e.message : "Failed to load");
    }).finally(() => {
      if (alive) setLoading(false);
    });
    return () => { alive = false; };
  }, [pageId]);

  return (
    <div className="fixed inset-0 z-50 flex justify-end">
      <button
        aria-label="Close"
        onClick={onClose}
        className="absolute inset-0 bg-slate-900/40 backdrop-blur-sm"
      />
      <div className="relative w-full max-w-3xl bg-white h-full overflow-y-auto shadow-2xl">
        <div className="sticky top-0 bg-white border-b border-slate-200 px-6 py-4 flex items-center justify-between z-10">
          <div className="min-w-0 flex-1">
            <div className="text-[10px] font-bold text-slate-500 uppercase">Page Lifecycle</div>
            <div className="text-sm font-mono text-slate-800 truncate">{history?.page.url ?? "Loading…"}</div>
          </div>
          <button
            onClick={onClose}
            className="p-1.5 rounded-lg hover:bg-slate-100 text-slate-500"
          >
            <X className="w-4 h-4" />
          </button>
        </div>

        {loading && <div className="p-12 text-center text-sm text-slate-500">Loading lifecycle…</div>}
        {err && <div className="p-8 text-center text-sm text-red-600">{err}</div>}

        {history && (
          <div className="p-6 space-y-6">
            {/* Status + meta header */}
            <div className="flex items-start justify-between gap-4">
              <div>
                <h2 className="text-lg font-bold text-slate-900">{history.page.title ?? history.page.url}</h2>
                <div className="flex items-center gap-2 mt-1 flex-wrap">
                  <StatusPill status={history.page.currentStatus} />
                  <span className="text-xs text-slate-500">First seen {formatDate(history.page.firstSeenAt)}</span>
                  <span className="text-xs text-slate-500">· {history.page.daysLive} days live</span>
                  {history.page.isInNav && (
                    <span className="text-[10px] font-bold uppercase bg-sky-100 text-sky-700 px-1.5 py-0.5 rounded">In navigation</span>
                  )}
                </div>
              </div>
              {history.page.fullUrl && (
                <a
                  href={history.page.fullUrl}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="flex items-center gap-1 text-xs font-bold text-brand-700 hover:text-brand-900 shrink-0"
                >
                  Open page <ArrowUpRight className="w-3 h-3" />
                </a>
              )}
            </div>

            {/* Comparison cards */}
            {compare && (
              <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                <DeltaCard label="Clicks" current={compare.current.clicks} previous={compare.previous.clicks} delta={compare.deltas.clicks} />
                <DeltaCard label="Impressions" current={compare.current.impressions} previous={compare.previous.impressions} delta={compare.deltas.impressions} />
                <DeltaCard label="CTR" current={compare.current.ctr} previous={compare.previous.ctr} delta={compare.deltas.ctr} format="percent" />
                <DeltaCard label="Avg Position" current={compare.current.avgPosition} previous={compare.previous.avgPosition} delta={compare.deltas.avgPosition} format="decimal" invertDelta />
              </div>
            )}

            {/* Chart */}
            {history.dailyMetrics.length > 0 ? (
              <div className="bg-slate-50 rounded-xl p-4">
                <div className="text-xs font-bold text-slate-500 uppercase mb-3">Performance over time</div>
                <div className="h-60">
                  <ResponsiveContainer width="100%" height="100%">
                    <LineChart data={history.dailyMetrics.map(d => ({ ...d, dateLabel: formatDate(d.date) }))}>
                      <CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
                      <XAxis dataKey="dateLabel" tick={{ fontSize: 10 }} stroke="#94a3b8" />
                      <YAxis tick={{ fontSize: 10 }} stroke="#94a3b8" />
                      <RTooltip contentStyle={{ fontSize: "11px", borderRadius: "8px" }} />
                      <Line type="monotone" dataKey="clicks" stroke="#0D9488" strokeWidth={2} dot={false} name="Clicks" />
                      <Line type="monotone" dataKey="impressions" stroke="#94a3b8" strokeWidth={1.5} strokeDasharray="4 4" dot={false} name="Impressions" />
                    </LineChart>
                  </ResponsiveContainer>
                </div>
              </div>
            ) : (
              <div className="bg-slate-50 rounded-xl p-6 text-center text-xs text-slate-500">
                No GSC performance data for this page yet. Connect Google Search Console to populate historical clicks and impressions.
              </div>
            )}

            {/* Timeline */}
            <div>
              <div className="text-xs font-bold text-slate-500 uppercase mb-3 flex items-center gap-1">
                <Clock className="w-3 h-3" /> Status Timeline
              </div>
              <div className="space-y-2">
                {history.timeline.map((t, i) => <TimelineRow key={i} event={t} />)}
              </div>
            </div>

            {/* Redirect map */}
            {(history.redirectsIn.length > 0 || history.redirectsOut.length > 0) && (
              <div>
                <div className="text-xs font-bold text-slate-500 uppercase mb-3">Redirect Map</div>
                <div className="bg-slate-50 rounded-xl p-4 space-y-2">
                  {history.redirectsIn.map(r => (
                    <div key={r.id} className="flex items-center gap-2 text-xs font-mono">
                      <span className="text-slate-700 truncate flex-1">{r.sourceUrl}</span>
                      <span className="text-[10px] text-amber-600 font-bold">→ {r.statusCode} →</span>
                      <span className="text-emerald-700 truncate flex-1">{r.targetUrl}</span>
                      <span className="text-[10px] text-slate-400 shrink-0">since {relativeTime(r.firstSeenAt)}</span>
                    </div>
                  ))}
                  {history.redirectsOut.map(r => (
                    <div key={r.id} className="flex items-center gap-2 text-xs font-mono">
                      <span className="text-slate-700 truncate flex-1">(this page)</span>
                      <span className="text-[10px] text-amber-600 font-bold">→ {r.statusCode} →</span>
                      <span className="text-amber-700 truncate flex-1">{r.targetUrl}</span>
                      <span className="text-[10px] text-slate-400 shrink-0">since {relativeTime(r.firstSeenAt)}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Page metadata */}
            <div>
              <div className="text-xs font-bold text-slate-500 uppercase mb-3">Page Metadata</div>
              <div className="bg-slate-50 rounded-xl p-4 space-y-2 text-xs">
                <MetaRow label="Title" value={history.page.title} />
                <MetaRow label="Meta description" value={history.page.metaDescription} />
                <MetaRow label="H1" value={history.page.h1} />
                <MetaRow label="Canonical" value={history.page.canonicalUrl} />
                <MetaRow label="Word count" value={history.page.wordCount != null ? String(history.page.wordCount) : null} />
                <MetaRow label="Total visits (Site Tag)" value={String(history.page.totalVisits)} />
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function StatusPill({ status }: { status: number }) {
  const s = statusColor(status);
  return (
    <span className={`text-[10px] font-bold ${s.bg} ${s.text} px-1.5 py-0.5 rounded inline-flex items-center gap-1`}>
      <span className={`w-1.5 h-1.5 rounded-full ${s.dot}`} />
      {s.label}
    </span>
  );
}

function DeltaCard({
  label, current, previous, delta, format = "number", invertDelta = false,
}: {
  label: string;
  current: number;
  previous: number;
  delta: { absolute: number; relative: number };
  format?: "number" | "percent" | "decimal";
  invertDelta?: boolean;
}) {
  const fmt = (n: number) =>
    format === "percent" ? `${n.toFixed(1)}%`
    : format === "decimal" ? n.toFixed(1)
    : formatNumber(Math.round(n));

  // For position, a decrease is an improvement; flip the indicator color
  const effectiveRelative = invertDelta ? -delta.relative : delta.relative;
  const isUp = effectiveRelative > 0;
  const neutral = Math.abs(delta.relative) < 0.1;

  return (
    <div className="bg-white border border-slate-200 rounded-xl p-3">
      <div className="text-[10px] font-bold text-slate-500 uppercase">{label}</div>
      <div className="text-xl font-bold text-slate-900 mt-1">{fmt(current)}</div>
      <div className="flex items-center gap-1 mt-1 text-[10px]">
        {neutral ? (
          <span className="text-slate-400">No change</span>
        ) : isUp ? (
          <span className="flex items-center gap-0.5 text-emerald-600 font-semibold">
            <TrendingUp className="w-3 h-3" /> {Math.abs(delta.relative).toFixed(1)}%
          </span>
        ) : (
          <span className="flex items-center gap-0.5 text-red-600 font-semibold">
            <TrendingDown className="w-3 h-3" /> {Math.abs(delta.relative).toFixed(1)}%
          </span>
        )}
        <span className="text-slate-400">vs {fmt(previous)}</span>
      </div>
    </div>
  );
}

function TimelineRow({ event }: { event: { at: string; type: string; label: string; status?: number } }) {
  const colorMap: Record<string, string> = {
    first_seen: "bg-emerald-500",
    added_to_nav: "bg-sky-500",
    removed_from_nav: "bg-slate-500",
    status_change: event.status === 404 ? "bg-red-500" : event.status && event.status >= 300 && event.status < 400 ? "bg-amber-500" : "bg-emerald-500",
    redirect_in: "bg-amber-500",
    redirect_out: "bg-amber-500",
    traffic_milestone: "bg-indigo-500",
  };
  const dot = colorMap[event.type] ?? "bg-slate-400";
  return (
    <div className="flex items-start gap-3 text-xs">
      <div className="relative flex flex-col items-center">
        <div className={`w-2.5 h-2.5 rounded-full ${dot} ring-2 ring-white shadow`} />
      </div>
      <div className="flex-1 min-w-0 pb-2 border-b border-slate-100">
        <div className="text-slate-700">{event.label}</div>
        <div className="text-[10px] text-slate-400">{formatDate(event.at)}</div>
      </div>
    </div>
  );
}

function MetaRow({ label, value }: { label: string; value: string | null }) {
  return (
    <div className="flex items-start gap-2">
      <span className="text-slate-500 font-semibold shrink-0 w-36">{label}</span>
      <span className="text-slate-800 break-all flex-1">{value || <span className="text-slate-400">—</span>}</span>
    </div>
  );
}
