"use client";

import { useEffect, useMemo, useState } from "react";

import { BACKEND } from "../config";

type CanonicalPostRow = {
  id: number;
  title?: string | null;
  created_at?: string | null;
  platform_posts: Array<{
    platform: string;
    platform_post_id: string;
    permalink?: string | null;
    created_time?: string | null;
    comment_count_api?: number | null;
    reaction_count_api?: number | null;
    share_count_api?: number | null;
    match_confidence?: number | null;
  }>;
};

type StoredComment = {
  comment_id: string;
  username?: string;
  text?: string;
  timestamp?: string;
  like_count?: number;
  created_at?: string;
};

type CommentAnalysisItem = {
  comment_id: string;
  language?: string | null;
  sentiment_label?: string | null;
  sentiment_score?: number | null;
  emotion_primary?: string | null;
  emotion_confidence?: number | null;
  intent_type?: string | null;
  intent_confidence?: number | null;
  topics?: Array<{ label: string; confidence: number }>;
  toxicity_is_toxic?: boolean | null;
  toxicity_level?: number | null;
  purchase_is_signal?: boolean | null;
  purchase_confidence?: number | null;
  summary?: string | null;
  needs_context?: boolean | null;
  flags?: string[];
  model?: string | null;
  prompt_version?: string | null;
  created_at?: string | null;
};

type AiCanonicalSummary = {
  ok: true;
  canonical_post_id: number;
  platforms: Record<
    string,
    {
      platform: string;
      platform_post_id: string;
      permalink?: string | null;
      created_time?: string | null;
      match_confidence?: number | null;
      comments_stored: number;
      analyses_stored: number;
      last_analysis_at?: string | null;
    }
  >;
  aggregate: {
    totals: {
      analyses: number;
      toxic: number;
      purchase_signal: number;
      needs_context: number;
    };
    sentiment: Record<string, number>;
    intent: Record<string, number>;
    emotion: Record<string, number>;
    language: Record<string, number>;
    topics: Record<string, number>;
    latest_created_at?: string | null;
    last_analysis_at?: string | null;
  };
};

type GlobalKpis = {
  ok: true;
  aggregate: AiCanonicalSummary["aggregate"];
};


async function safeJson(res: Response) {
  try {
    return await res.json();
  } catch {
    return null;
  }
}


function pct(part: number, total: number) {
  if (!total) return 0;
  return Math.round((part / total) * 1000) / 10;
}

function toInt(v: unknown, fallback = 0) {
  const n = Number(v);
  return Number.isFinite(n) ? n : fallback;
}

function fmtDate(iso?: string | null) {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleString();
  } catch {
    return String(iso);
  }
}

function Badge(props: { text: string }) {
  return (
    <span className="inline-flex items-center rounded-full bg-white/10 px-2 py-0.5 text-xs text-white/80">
      {props.text}
    </span>
  );
}

function StatBox(props: { label: string; value: number | string }) {
  return (
    <div className="futuristic-panel rounded-xl border border-white/10 bg-white/5 p-3">
      <div className="text-xs text-white/60">{props.label}</div>
      <div className="mt-1 text-lg font-semibold">{props.value}</div>
    </div>
  );
}

export default function DashboardPage() {
  const [canonicalPosts, setCanonicalPosts] = useState<CanonicalPostRow[]>([]);
  const [selectedCanonicalId, setSelectedCanonicalId] = useState<number | null>(null);

  const [aiSummary, setAiSummary] = useState<AiCanonicalSummary | null>(null);
  const [loadingSummary, setLoadingSummary] = useState(false);


  const [globalKpis, setGlobalKpis] = useState<GlobalKpis | null>(null);
  const [globalKpisMode, setGlobalKpisMode] = useState<"count" | "percent">("count");

  const [analyzing, setAnalyzing] = useState(false);
  const [analyzingType, setAnalyzingType] = useState<"new" | "all" | null>(null);
  const [lastAnalyze, setLastAnalyze] = useState<any | null>(null);

  const [refreshingPlatforms, setRefreshingPlatforms] = useState(false);
  const [lastPlatformRefresh, setLastPlatformRefresh] = useState<any | null>(null);

  const [rows, setRows] = useState<
    Array<
      {
        platform: string;
        platform_post_id: string;
        comment: StoredComment;
        analysis?: CommentAnalysisItem;
      }
    >
  >([]);

  const [filterPlatform, setFilterPlatform] = useState<string>("all");
  const [filterSentiment, setFilterSentiment] = useState<string>("all");
  const [filterIntent, setFilterIntent] = useState<string>("all");
  const [filterTopic, setFilterTopic] = useState<string>("all");
  const [search, setSearch] = useState<string>("");

  useEffect(() => {
    (async () => {
      const res = await fetch(`${BACKEND}/canonical/list`, { credentials: "include" });
      const j = await safeJson(res);
      if (Array.isArray(j)) {
        setCanonicalPosts(j);
        if (j.length && selectedCanonicalId == null) {
          setSelectedCanonicalId(Number(j[0].id));
        }
      }
    })();
  }, []);

  useEffect(() => {
    (async () => {
      const res = await fetch(`${BACKEND}/ai/global/kpis`, { credentials: "include" });
      const j = await safeJson(res);
      if (j && j.ok) setGlobalKpis(j);
      else setGlobalKpis(null);
    })();
  }, []);

  const selectedCanonical = useMemo(() => {
    if (selectedCanonicalId == null) return null;
    return canonicalPosts.find((c) => Number(c.id) === Number(selectedCanonicalId)) || null;
  }, [canonicalPosts, selectedCanonicalId]);

  async function refreshAiSummary() {
    if (selectedCanonicalId == null) return;
    setLoadingSummary(true);
    try {
      const res = await fetch(`${BACKEND}/ai/canonical/summary?canonical_post_id=${selectedCanonicalId}`, { credentials: "include" });
      const j = await safeJson(res);
      if (j && j.ok) setAiSummary(j);
      else setAiSummary(null);
    } finally {
      setLoadingSummary(false);
    }
  }

  async function loadRows() {
    if (!selectedCanonical) return;
    const newRows: Array<{ platform: string; platform_post_id: string; comment: StoredComment; analysis?: CommentAnalysisItem }> = [];

    for (const pp of selectedCanonical.platform_posts || []) {
      const p = pp.platform;
      const pid = String(pp.platform_post_id);

      const [commentsRes, analysesRes] = await Promise.all([
        fetch(`${BACKEND}/comments?platform=${encodeURIComponent(p)}&platform_post_id=${encodeURIComponent(pid)}`, { credentials: "include" }),
        fetch(`${BACKEND}/ai/analyses?platform=${encodeURIComponent(p)}&platform_post_id=${encodeURIComponent(pid)}`, { credentials: "include" }),
      ]);

      const commentsJson = await safeJson(commentsRes);
      const analysesJson = await safeJson(analysesRes);

      const analysesMap: Record<string, CommentAnalysisItem> = {};
      if (analysesJson && analysesJson.ok && Array.isArray(analysesJson.items)) {
        for (const a of analysesJson.items) {
          if (a && a.comment_id) analysesMap[String(a.comment_id)] = a;
        }
      }

      if (Array.isArray(commentsJson)) {
        for (const c of commentsJson) {
          if (!c || !c.comment_id) continue;
          newRows.push({ platform: p, platform_post_id: pid, comment: c, analysis: analysesMap[String(c.comment_id)] });
        }
      }
    }

    newRows.sort((a, b) => {
      const ta = new Date(a.comment.created_at || 0).getTime();
      const tb = new Date(b.comment.created_at || 0).getTime();
      return tb - ta;
    });

    setRows(newRows);
  }

  useEffect(() => {
    (async () => {
      setAiSummary(null);
      setRows([]);
      await refreshAiSummary();
      await loadRows();
    })();
  }, [selectedCanonicalId]);

  const platformOptions = useMemo(() => {
    const s = new Set<string>();
    for (const r of rows) s.add(r.platform);
    return Array.from(s).sort();
  }, [rows]);

  const sentimentOptions = useMemo(() => {
    const s = new Set<string>();
    for (const r of rows) if (r.analysis?.sentiment_label) s.add(String(r.analysis.sentiment_label));
    return Array.from(s).sort();
  }, [rows]);

  const intentOptions = useMemo(() => {
    const s = new Set<string>();
    for (const r of rows) if (r.analysis?.intent_type) s.add(String(r.analysis.intent_type));
    return Array.from(s).sort();
  }, [rows]);

  const topicOptions = useMemo(() => {
    const s = new Set<string>();
    for (const r of rows) {
      for (const t of r.analysis?.topics || []) {
        if (t?.label) s.add(String(t.label));
      }
    }
    return Array.from(s).sort();
  }, [rows]);

  const filteredRows = useMemo(() => {
    const q = search.trim().toLowerCase();

    return rows.filter((r) => {
      if (filterPlatform !== "all" && r.platform !== filterPlatform) return false;
      if (filterSentiment !== "all" && String(r.analysis?.sentiment_label || "") !== filterSentiment) return false;
      if (filterIntent !== "all" && String(r.analysis?.intent_type || "") !== filterIntent) return false;
      if (filterTopic !== "all") {
        const has = (r.analysis?.topics || []).some((t) => String(t?.label || "") === filterTopic);
        if (!has) return false;
      }

      if (q) {
        const t = String(r.comment.text || "").toLowerCase();
        const u = String(r.comment.username || "").toLowerCase();
        if (!t.includes(q) && !u.includes(q)) return false;
      }

      return true;
    });
  }, [rows, filterPlatform, filterSentiment, filterIntent, filterTopic, search]);

  async function runAiAnalyzeNew() {
    if (selectedCanonicalId == null) return;
    setAnalyzing(true);
    setAnalyzingType("new");
    setLastAnalyze(null);
    try {
      const res = await fetch(`${BACKEND}/ai/canonical/analyze?canonical_post_id=${selectedCanonicalId}&limit_per_platform_post=200&force=0`, {
        method: "POST",
        credentials: "include",
      });
      const j = await safeJson(res);
      setLastAnalyze(j);
      await refreshAiSummary();
      await loadRows();
    } finally {
      setAnalyzing(false);
      setAnalyzingType(null);
    }
  }

  async function runAiAnalyzeAll() {
    if (selectedCanonicalId == null) return;
    setAnalyzing(true);
    setAnalyzingType("all");
    setLastAnalyze(null);
    try {
      const res = await fetch(`${BACKEND}/ai/canonical/analyze?canonical_post_id=${selectedCanonicalId}&limit_per_platform_post=200&force=1`, {
        method: "POST",
        credentials: "include",
      });
      const j = await safeJson(res);
      setLastAnalyze(j);
      await refreshAiSummary();
      await loadRows();
    } finally {
      setAnalyzing(false);
      setAnalyzingType(null);
    }
  }

  async function refreshFromPlatforms() {
    if (selectedCanonicalId == null) return;
    setRefreshingPlatforms(true);
    setLastPlatformRefresh(null);
    try {
      const res = await fetch(`${BACKEND}/canonical/refresh?canonical_post_id=${selectedCanonicalId}`, {
        method: "POST",
        credentials: "include",
      });
      const j = await safeJson(res);
      setLastPlatformRefresh(j);
      await refreshAiSummary();
      await loadRows();
    } finally {
      setRefreshingPlatforms(false);
    }
  }

  return (
    <main className="min-h-screen bg-black text-white">
      <div className="mx-auto max-w-6xl p-6">
        <div className="flex flex-col gap-2">
          <div className="flex items-center justify-between gap-4">
            <div className="text-2xl font-semibold">Social Analytics Dashboard</div>
            <div className="flex gap-2">
              <a
                href="/toxicity"
                className="futuristic-btn rounded-xl border border-white/20 bg-transparent px-3 py-2 text-sm text-white/80 hover:bg-white/10"
              >
                Toxicity Review
              </a>
              <a
                href="/analytics"
                className="futuristic-btn rounded-xl border border-white/20 bg-transparent px-3 py-2 text-sm text-white/80 hover:bg-white/10"
              >
                Analytics
              </a>
              <a
                href="/settings"
                className="futuristic-btn rounded-xl border border-white/20 bg-transparent px-3 py-2 text-sm text-white/80 hover:bg-white/10"
              >
                Settings
              </a>
              <a
                href="/"
                className="futuristic-btn rounded-xl border border-white/20 bg-transparent px-3 py-2 text-sm text-white/80 hover:bg-white/10"
              >
                Back to Home
              </a>
            </div>
          </div>
          <div className="text-sm text-white/60">Canonical posts, comments, and OpenAI analyses</div>

        <div className="futuristic-panel mt-6 rounded-2xl border border-white/10 bg-white/5 p-4">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <div>
              <div className="text-lg font-semibold">Global KPIs</div>
              <div className="text-sm text-white/60">
                {globalKpis?.aggregate?.last_analysis_at ? `Last OpenAI analysis ${fmtDate(globalKpis.aggregate.last_analysis_at)}` : ""}
              </div>
            </div>

            <div className="flex items-center gap-2">
              <button
                className={`futuristic-btn rounded-lg border px-3 py-1.5 text-sm ${globalKpisMode === "count" ? "border-white/30 bg-white/10" : "border-white/10 bg-transparent"}`}
                onClick={() => setGlobalKpisMode("count")}
                type="button"
              >
                Count
              </button>
              <button
                className={`futuristic-btn rounded-lg border px-3 py-1.5 text-sm ${globalKpisMode === "percent" ? "border-white/30 bg-white/10" : "border-white/10 bg-transparent"}`}
                onClick={() => setGlobalKpisMode("percent")}
                type="button"
              >
                Percent
              </button>
            </div>
          </div>

          <div className="mt-4 grid grid-cols-2 gap-3 md:grid-cols-4">
            <div className="rounded-xl border border-white/10 bg-black/30 p-3">
              <div className="text-xs text-white/60">Analyses</div>
              <div className="mt-1 text-xl font-semibold">
                {globalKpis ? globalKpis.aggregate.totals.analyses : 0}
              </div>
            </div>

            <div className="rounded-xl border border-white/10 bg-black/30 p-3">
              <div className="text-xs text-white/60">Toxic</div>
              <div className="mt-1 text-xl font-semibold">
                {globalKpis
                  ? globalKpisMode === "count"
                    ? globalKpis.aggregate.totals.toxic
                    : `${pct(globalKpis.aggregate.totals.toxic, globalKpis.aggregate.totals.analyses)}%`
                  : 0}
              </div>
            </div>

            <div className="rounded-xl border border-white/10 bg-black/30 p-3">
              <div className="text-xs text-white/60">Purchase signal</div>
              <div className="mt-1 text-xl font-semibold">
                {globalKpis
                  ? globalKpisMode === "count"
                    ? globalKpis.aggregate.totals.purchase_signal
                    : `${pct(globalKpis.aggregate.totals.purchase_signal, globalKpis.aggregate.totals.analyses)}%`
                  : 0}
              </div>
            </div>

            <div className="rounded-xl border border-white/10 bg-black/30 p-3">
              <div className="text-xs text-white/60">Needs context</div>
              <div className="mt-1 text-xl font-semibold">
                {globalKpis
                  ? globalKpisMode === "count"
                    ? globalKpis.aggregate.totals.needs_context
                    : `${pct(globalKpis.aggregate.totals.needs_context, globalKpis.aggregate.totals.analyses)}%`
                  : 0}
              </div>
            </div>
          </div>
        </div>

        </div>

        <div className="futuristic-panel mt-6 grid grid-cols-1 gap-4 rounded-2xl border border-white/10 bg-white/5 p-4 md:grid-cols-3">
          <div className="md:col-span-2">
            <div className="text-sm text-white/60">Canonical post</div>
            <select
              className="mt-2 w-full rounded-xl border border-white/10 bg-black/60 p-2 text-sm"
              value={selectedCanonicalId ?? ""}
              onChange={(e) => setSelectedCanonicalId(Number(e.target.value))}
            >
              {canonicalPosts.map((c) => (
                <option key={c.id} value={c.id}>
                  #{c.id} {c.title ? String(c.title).slice(0, 80) : "Untitled"}
                </option>
              ))}
            </select>
            <div className="mt-2 text-xs text-white/60">Created {fmtDate(selectedCanonical?.created_at || null)}</div>
          </div>

          <div className="flex flex-col justify-end gap-2">
            <div className="flex gap-2">
              <button
                className={`rounded-xl px-4 py-2 text-sm font-semibold disabled:opacity-60 ${
                  analyzing && analyzingType === "new"
                    ? "bg-blue-600 text-white"
                    : "bg-white text-black"
                }`}
                onClick={runAiAnalyzeNew}
                disabled={analyzing || selectedCanonicalId == null}
              >
                {analyzing && analyzingType === "new" ? (
                  <span className="flex items-center gap-2">
                    <span className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></span>
                    Analyzing New...
                  </span>
                ) : (
                  "Analyze New"
                )}
              </button>
              <button
                className={`rounded-xl px-4 py-2 text-sm font-semibold disabled:opacity-60 ${
                  analyzing && analyzingType === "all"
                    ? "bg-blue-600 text-white"
                    : "bg-gray-600 text-white"
                }`}
                onClick={runAiAnalyzeAll}
                disabled={analyzing || selectedCanonicalId == null}
              >
                {analyzing && analyzingType === "all" ? (
                  <span className="flex items-center gap-2">
                    <span className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></span>
                    Reprocessing All...
                  </span>
                ) : (
                  "Reprocess All"
                )}
              </button>
            </div>
            {analyzing && (
              <div className="mt-2 flex items-center gap-2 text-xs text-blue-400">
                <span className="inline-block h-3 w-3 animate-spin rounded-full border-2 border-blue-400 border-t-transparent"></span>
                <span>
                  {analyzingType === "new"
                    ? "Analyzing new comments only..."
                    : "Reprocessing all comments (this may take a while)..."}
                </span>
              </div>
            )}
            {!analyzing && (aiSummary?.aggregate?.last_analysis_at || aiSummary?.aggregate?.latest_created_at) && (
              <div className="mt-2 text-xs text-white/60">
                Last OpenAI analysis {fmtDate(aiSummary.aggregate.last_analysis_at || aiSummary.aggregate.latest_created_at || null)}
              </div>
            )}
            {!analyzing && !aiSummary?.aggregate?.last_analysis_at && !aiSummary?.aggregate?.latest_created_at && (
              <div className="mt-2 text-xs text-white/60">Last OpenAI analysis none</div>
            )}

            <button
              className="futuristic-btn mt-3 rounded-xl border border-white/20 bg-transparent px-4 py-2 text-sm text-white/80 disabled:opacity-60"
              onClick={refreshFromPlatforms}
              disabled={refreshingPlatforms || selectedCanonicalId == null}
            >
              {refreshingPlatforms ? "Refreshing platforms" : "Refresh from platforms"}
            </button>

            <button
              className="futuristic-btn mt-2 rounded-xl border border-white/20 bg-transparent px-4 py-2 text-sm text-white/80 disabled:opacity-60"
              onClick={() => {
                refreshAiSummary();
                loadRows();
              }}
              disabled={loadingSummary || selectedCanonicalId == null}
            >
              Refresh
            </button>
          </div>
        </div>

        {lastPlatformRefresh ? (
          <div className="futuristic-panel mt-4 rounded-2xl border border-white/10 bg-white/5 p-4">
            <div className="text-sm font-semibold">Last platform refresh run</div>
            {lastPlatformRefresh?.refresh?.facebook?.ok === false ? (
              <div className="mt-2 rounded-xl border border-red-500/30 bg-red-500/10 p-3">
                <div className="text-sm font-semibold text-red-200">Facebook refresh failed</div>
                <div className="mt-1 text-sm text-white/70">
                  The Meta token used by the backend is missing required permissions for Facebook Page comments.
                </div>
                <div className="mt-2 text-xs text-white/60">
                  Next steps
                  <ol className="mt-1 list-decimal pl-5">
                    <li>Open {BACKEND}/meta/debug/token to verify granted scopes</li>
                    <li>Reconnect Meta from the main screen so the new permissions are granted</li>
                    <li>Then click Refresh from platforms again</li>
                  </ol>
                </div>
              </div>
            ) : null}
            <pre className="mt-2 max-h-64 overflow-auto rounded-xl bg-black/50 p-3 text-xs text-white/70">
              {JSON.stringify(lastPlatformRefresh, null, 2)}
            </pre>
          </div>
        ) : null}

        <div className="futuristic-panel mt-6 rounded-2xl border border-white/10 bg-white/5 p-4">
          <div className="flex items-center justify-between gap-4">
            <div className="text-lg font-semibold">OpenAI summary</div>
            {aiSummary?.aggregate?.last_analysis_at || aiSummary?.aggregate?.latest_created_at ? (
              <div className="text-xs text-white/60">
                Last OpenAI analysis {fmtDate(aiSummary.aggregate.last_analysis_at || aiSummary.aggregate.latest_created_at || null)}
              </div>
            ) : null}
          </div>

          {aiSummary ? (
            <div className="mt-4 grid grid-cols-2 gap-3 md:grid-cols-4">
              <StatBox label="Analyses" value={toInt(aiSummary.aggregate.totals.analyses)} />
              <StatBox label="Toxic" value={toInt(aiSummary.aggregate.totals.toxic)} />
              <StatBox label="Purchase" value={toInt(aiSummary.aggregate.totals.purchase_signal)} />
              <StatBox label="Needs context" value={toInt(aiSummary.aggregate.totals.needs_context)} />
            </div>
          ) : (
            <div className="mt-3 text-sm text-white/60">No summary yet</div>
          )}

          {aiSummary ? (
            <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-3">
              <div className="rounded-xl border border-white/10 bg-black/40 p-3">
                <div className="text-sm font-semibold">Sentiment</div>
                <div className="mt-2 text-sm text-white/70">
                  {Object.entries(aiSummary.aggregate.sentiment).length ? (
                    Object.entries(aiSummary.aggregate.sentiment)
                      .sort((a, b) => b[1] - a[1])
                      .map(([k, v]) => (
                        <div key={k} className="flex items-center justify-between">
                          <span>{k}</span>
                          <span>{v}</span>
                        </div>
                      ))
                  ) : (
                    <div className="text-white/60">No data</div>
                  )}
                </div>
              </div>

              <div className="rounded-xl border border-white/10 bg-black/40 p-3">
                <div className="text-sm font-semibold">Intent</div>
                <div className="mt-2 text-sm text-white/70">
                  {Object.entries(aiSummary.aggregate.intent).length ? (
                    Object.entries(aiSummary.aggregate.intent)
                      .sort((a, b) => b[1] - a[1])
                      .map(([k, v]) => (
                        <div key={k} className="flex items-center justify-between">
                          <span>{k}</span>
                          <span>{v}</span>
                        </div>
                      ))
                  ) : (
                    <div className="text-white/60">No data</div>
                  )}
                </div>
              </div>

              <div className="rounded-xl border border-white/10 bg-black/40 p-3">
                <div className="text-sm font-semibold">Top topics</div>
                <div className="mt-2 text-sm text-white/70">
                  {Object.entries(aiSummary.aggregate.topics).length ? (
                    Object.entries(aiSummary.aggregate.topics)
                      .sort((a, b) => b[1] - a[1])
                      .slice(0, 10)
                      .map(([k, v]) => (
                        <div key={k} className="flex items-center justify-between">
                          <span>{k}</span>
                          <span>{v}</span>
                        </div>
                      ))
                  ) : (
                    <div className="text-white/60">No data</div>
                  )}
                </div>
              </div>
            </div>
          ) : null}
        </div>

        <div className="futuristic-panel mt-6 rounded-2xl border border-white/10 bg-white/5 p-4">
          <div className="flex flex-col gap-3 md:flex-row md:items-end md:justify-between">
            <div>
              <div className="text-lg font-semibold">Comments</div>
              <div className="text-xs text-white/60">Merged raw comments and OpenAI analyses</div>
            </div>

            <div className="grid grid-cols-2 gap-2 md:grid-cols-5">
              <select
                className="rounded-xl border border-white/10 bg-black/60 p-2 text-xs"
                value={filterPlatform}
                onChange={(e) => setFilterPlatform(e.target.value)}
              >
                <option value="all">All platforms</option>
                {platformOptions.map((p) => (
                  <option key={p} value={p}>
                    {p}
                  </option>
                ))}
              </select>

              <select
                className="rounded-xl border border-white/10 bg-black/60 p-2 text-xs"
                value={filterSentiment}
                onChange={(e) => setFilterSentiment(e.target.value)}
              >
                <option value="all">All sentiment</option>
                {sentimentOptions.map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>

              <select
                className="rounded-xl border border-white/10 bg-black/60 p-2 text-xs"
                value={filterIntent}
                onChange={(e) => setFilterIntent(e.target.value)}
              >
                <option value="all">All intent</option>
                {intentOptions.map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>

              <select
                className="rounded-xl border border-white/10 bg-black/60 p-2 text-xs"
                value={filterTopic}
                onChange={(e) => setFilterTopic(e.target.value)}
              >
                <option value="all">All topics</option>
                {topicOptions.map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>

              <input
                className="futuristic-input col-span-2 rounded-xl border border-white/10 bg-black/60 p-2 text-xs md:col-span-1"
                placeholder="Search"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />
            </div>
          </div>

          <div className="mt-3 text-xs text-white/60">
            Showing {filteredRows.length} of {rows.length}
          </div>

          <div className="mt-4 space-y-3">
            {filteredRows.slice(0, 500).map((r) => {
              const a = r.analysis;
              const topics = (a?.topics || []).slice(0, 3);

              return (
                <div key={`${r.platform}:${r.platform_post_id}:${r.comment.comment_id}`} className="rounded-2xl border border-white/10 bg-black/40 p-4">
                  <div className="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
                    <div className="min-w-0">
                      <div className="text-sm font-semibold">
                        {r.comment.username || "Unknown"} <span className="text-white/40">on {r.platform}</span>
                      </div>
                      <div className="mt-1 text-xs text-white/60">{fmtDate(r.comment.created_at || null)}</div>
                      <div className="mt-3 whitespace-pre-wrap text-sm text-white/80">{r.comment.text || ""}</div>
                    </div>

                    <div className="shrink-0 space-y-2">
                      <div className="flex flex-wrap gap-2">
                        {a?.sentiment_label ? <Badge text={`sentiment ${a.sentiment_label} ${toInt(a.sentiment_score)}%`} /> : <Badge text="no analysis" />}
                        {a?.intent_type ? <Badge text={`intent ${a.intent_type} ${toInt(a.intent_confidence)}%`} /> : null}
                        {a?.emotion_primary ? <Badge text={`emotion ${a.emotion_primary} ${toInt(a.emotion_confidence)}%`} /> : null}
                        {a?.toxicity_is_toxic ? <Badge text={`toxic ${toInt(a.toxicity_level)}%`} /> : null}
                        {a?.purchase_is_signal ? <Badge text={`purchase ${toInt(a.purchase_confidence)}%`} /> : null}
                        {a?.needs_context ? <Badge text="needs context" /> : null}
                      </div>
                      {topics.length ? (
                        <div className="flex flex-wrap gap-2">
                          {topics.map((t, idx) => (
                            <Badge key={idx} text={`topic ${t.label} ${toInt((t.confidence || 0) * 100)}%`} />
                          ))}
                        </div>
                      ) : null}
                      {a?.summary ? <div className="max-w-xs text-xs text-white/60">{a.summary}</div> : null}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {lastAnalyze && !analyzing ? (
          <div className="mt-6 rounded-2xl border border-white/10 bg-white/5 p-4">
            <div className="mb-3 text-sm font-semibold">Analysis Results</div>
            {lastAnalyze.ok && lastAnalyze.results ? (
              <div className="space-y-3">
                {Array.isArray(lastAnalyze.results) && lastAnalyze.results.length > 0 ? (
                  lastAnalyze.results.map((result: any, idx: number) => (
                    <div key={idx} className="rounded-lg border border-white/10 bg-black/40 p-3">
                      <div className="mb-2 flex items-center justify-between">
                        <span className="text-sm font-semibold capitalize text-white">
                          {result.platform || "Unknown"}
                        </span>
                        <span className="text-xs text-white/60">
                          {result.analyzed || 0} analyzed, {result.skipped || 0} skipped
                          {result.failed && result.failed.length > 0 && (
                            <span className="ml-2 text-red-400">{result.failed.length} failed</span>
                          )}
                        </span>
                      </div>
                      <div className="text-xs text-white/60">
                        Requested: {result.requested || 0} comments
                      </div>
                    </div>
                  ))
                ) : (
                  <div className="text-sm text-white/60">No results available</div>
                )}
                <div className="mt-3 rounded-lg border border-white/10 bg-black/40 p-2 text-xs text-white/60">
                  Model: {lastAnalyze.model || "N/A"} | Force: {lastAnalyze.force ? "Yes" : "No"}
                </div>
              </div>
            ) : (
              <pre className="mt-3 max-h-96 overflow-auto rounded-xl border border-white/10 bg-black/60 p-3 text-xs text-white/80">
                {JSON.stringify(lastAnalyze, null, 2)}
              </pre>
            )}
          </div>
        ) : null}
      </div>
    </main>
  );
}
