"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";

import { BACKEND } from "./config";

type IgMedia = {
  id: string;
  caption?: string;
  media_type?: string;
  media_url?: string;
  permalink?: string;
  timestamp?: string;
  like_count?: number;
  comments_count?: number;
};

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 SyncResult =
  | {
      ok: true;
      media_id: string;
      saved_total: number;
      saved_top_level: number;
      saved_replies: number;
    }
  | {
      ok: false;
      error?: string;
      detail?: string;
      status_code?: number;
      error_response?: unknown;
    };

type VerifyResult =
  | {
      media_id: string;
      api_comments_count: number | null;
      stored_total: number;
      stored_top_level: number;
      stored_replies: number;
    }
  | {
      ok: false;
      error?: string;
      detail?: string;
      status_code?: number;
      error_response?: unknown;
    };

type CanonicalSummaryOk = {
  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;
      comment_count_api?: number | null;
      reaction_count_api?: number | null;
      share_count_api?: number | null;
      view_count_api?: number | null;
      comments_stored?: number | null;
    }
  >;
  totals: {
    comments_api: number;
    reactions_api: number;
    shares_api: number;
    views_api: number;
    comments_stored: number;
  };
};

type CanonicalSummary =
  | CanonicalSummaryOk
  | { ok: false; error?: string; detail?: string };

function truncate(s: string, n: number) {
  if (!s) return "";
  if (s.length <= n) return s;
  return s.slice(0, n - 1) + "…";
}

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

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

function findCanonicalIdForIgMediaId(igMediaId: string, canonicalPosts: any[]): number | null {
  for (const cp of canonicalPosts) {
    const pps = Array.isArray(cp.platform_posts) ? cp.platform_posts : [];
    for (const pp of pps) {
      if (pp.platform === "instagram" && String(pp.platform_post_id) === String(igMediaId)) {
        return Number(cp.id);
      }
    }
  }
  return null;
}

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

function MetricCard(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-white/60 text-sm">{props.label}</div>
      <div className="mt-1 text-xl font-semibold">{props.value}</div>
    </div>
  );
}

function PlatformRow(props: {
  platform: string;
  permalink?: string | null;
  commentCountApi?: number | null;
  reactionCountApi?: number | null;
  shareCountApi?: number | null;
  viewCountApi?: number | null;
  commentsStored?: number | null;
  matchConfidence?: number | null;
}) {
  const hasLink = Boolean(props.permalink);

  return (
    <div className="futuristic-panel rounded-2xl border border-white/10 bg-white/5 p-4">
      <div className="flex items-start justify-between gap-4">
        <div className="min-w-0">
          <div className="text-sm font-semibold">{props.platform}</div>
          {hasLink ? (
            <a
              className="mt-2 inline-block text-sm text-white underline underline-offset-4"
              href={String(props.permalink)}
              target="_blank"
              rel="noreferrer"
            >
              Open on {props.platform}
            </a>
          ) : (
            <div className="mt-2 text-sm text-white/60">No link available</div>
          )}
        </div>

        <div className="shrink-0 text-right text-xs text-white/60">
          {props.matchConfidence != null ? <div>Match {props.matchConfidence}</div> : null}
        </div>
      </div>

      <div className="mt-3 text-sm text-white/70">
        Stored comments {toInt(props.commentsStored)} <br />
        API comments {toInt(props.commentCountApi)} <br />
        API reactions {toInt(props.reactionCountApi)} <br />
        API shares {toInt(props.shareCountApi)} <br />
        API views {toInt(props.viewCountApi)}
      </div>
    </div>
  );
}

export default function Home() {
  const [backendStatus, setBackendStatus] = useState("loading");
  const [igUserId, setIgUserId] = useState<string | null>(null);

  const [media, setMedia] = useState<IgMedia[]>([]);
  const [selectedMediaId, setSelectedMediaId] = useState<string | null>(null);

  const [comments, setComments] = useState<StoredComment[]>([]);
  const [analyses, setAnalyses] = useState<Record<string, CommentAnalysisItem>>({});
  const [analyzing, setAnalyzing] = useState(false);
  const [lastAnalyzeResult, setLastAnalyzeResult] = useState<any | null>(null);
  const [syncingId, setSyncingId] = useState<string | null>(null);

  const [syncResult, setSyncResult] = useState<SyncResult | null>(null);
  const [verifyResult, setVerifyResult] = useState<VerifyResult | null>(null);

  const [error, setError] = useState<string | null>(null);

  const [igLink, setIgLink] = useState("");
  const [creatingCanon, setCreatingCanon] = useState(false);

  const [canonicalPosts, setCanonicalPosts] = useState<any[]>([]);
  const [trackingId, setTrackingId] = useState<string | null>(null);

  const [lastTrackResult, setLastTrackResult] = useState<any | null>(null);
  const [lastTrackAt, setLastTrackAt] = useState<string | null>(null);

  const [selectedCanonicalId, setSelectedCanonicalId] = useState<number | null>(null);
  const [canonicalSummary, setCanonicalSummary] = useState<CanonicalSummary | null>(null);
  const [editingFacebookPost, setEditingFacebookPost] = useState(false);
  const [facebookPostInput, setFacebookPostInput] = useState("");
  const [updatingFacebookPost, setUpdatingFacebookPost] = useState(false);

  const selected = useMemo(
    () => media.find((m) => m.id === selectedMediaId) ?? null,
    [media, selectedMediaId]
  );

  const coverage = useMemo(() => {
    if (!selected) return null;
    const apiCount = selected.comments_count ?? null;

    let storedTotal: number | null = null;
    if (verifyResult && "stored_total" in verifyResult) storedTotal = verifyResult.stored_total;

    if (apiCount === null || storedTotal === null) return null;
    if (apiCount === 0) return { apiCount, storedTotal, pct: 100 };

    const pct = Math.round((storedTotal / apiCount) * 100);
    return { apiCount, storedTotal, pct };
  }, [selected, verifyResult]);

  const fbPermalink = useMemo(() => {
    if (!canonicalSummary || !("ok" in canonicalSummary) || !canonicalSummary.ok) return null;
    const fb = canonicalSummary.platforms?.facebook;
    return fb?.permalink ? String(fb.permalink) : null;
  }, [canonicalSummary]);

  async function refreshHealth() {
    try {
      const res = await fetch(`${BACKEND}/health`, { credentials: "include" });
      const data = await safeJson(res);
      setBackendStatus(data?.status ?? "unknown");
    } catch {
      setBackendStatus("error");
    }
  }

  async function loadIgProfile() {
    setError(null);
    try {
      const res = await fetch(`${BACKEND}/meta/ig/profile`, { credentials: "include" });
      const data = await safeJson(res);
      if (!data?.ig_user_id) {
        setError("Missing ig_user_id from backend.");
        return;
      }
      setIgUserId(String(data.ig_user_id));
    } catch {
      setError("Could not load Instagram profile from backend.");
    }
  }

  async function loadMedia(igId: string) {
    setError(null);
    try {
      const res = await fetch(
        `${BACKEND}/meta/ig/media?ig_user_id=${encodeURIComponent(igId)}&limit=25`,
        { credentials: "include" }
      );
      const data = await safeJson(res);
      const items = Array.isArray(data?.data) ? (data.data as IgMedia[]) : [];
      setMedia(items);
      if (!selectedMediaId && items.length > 0) setSelectedMediaId(items[0].id);
    } catch {
      setError("Could not load Instagram posts.");
    }
  }

  async function loadStoredComments(mediaId: string) {
    setError(null);
    try {
      const res = await fetch(
        `${BACKEND}/comments?platform=instagram&platform_post_id=${encodeURIComponent(mediaId)}`,
        { credentials: "include" }
      );
      const data = await safeJson(res);
      setComments(Array.isArray(data) ? data : []);
    } catch {
      setError("Could not load stored comments.");
    }
  }

  async function loadAnalyses(mediaId: string) {
    setError(null);
    try {
      const res = await fetch(
        `${BACKEND}/ai/analyses?platform=instagram&platform_post_id=${encodeURIComponent(mediaId)}`,
        { credentials: "include" }
      );
      const data = await safeJson(res);
      if (!data?.ok || !Array.isArray(data.items)) {
        setAnalyses({});
        return;
      }
      const map: Record<string, CommentAnalysisItem> = {};
      for (const it of data.items) {
        if (it?.comment_id) map[String(it.comment_id)] = it as CommentAnalysisItem;
      }
      setAnalyses(map);
    } catch {
      setAnalyses({});
    }
  }

  async function analyzeWithOpenAI(mediaId: string, force: boolean = false) {
    setAnalyzing(true);
    setError(null);
    setLastAnalyzeResult(null);

    try {
      const res = await fetch(
        `${BACKEND}/ai/analyze?platform=instagram&platform_post_id=${encodeURIComponent(mediaId)}&limit=200&force=${force ? 1 : 0}`,
        { method: "POST", credentials: "include" }
      );
      const raw = await res.text().catch(() => "");
      let data: any | null = null;
      try {
        data = raw ? JSON.parse(raw) : null;
      } catch {
        data = null;
      }

      if (!res.ok) {
        const detail = data ? JSON.stringify(data) : truncate(raw || "", 600);
        setError(`OpenAI analyse failed. HTTP ${res.status}. ${detail}`);
        setLastAnalyzeResult(data ?? { ok: false, status: res.status, detail: detail || null });
        return;
      }

      if (!data) {
        setError(`OpenAI analyse returned no JSON. HTTP ${res.status}. ${truncate(raw || "", 600)}`);
        setLastAnalyzeResult({ ok: false, status: res.status, detail: truncate(raw || "", 600) });
        return;
      }

      setLastAnalyzeResult(data);
      await loadAnalyses(mediaId);
    } catch {
      setError("OpenAI analysis failed. Backend not reachable or OpenAI error.");
    } finally {
      setAnalyzing(false);
    }
  }

  async function runVerify(mediaId: string) {
    setVerifyResult(null);
    try {
      const res = await fetch(
        `${BACKEND}/meta/ig/comments/verify?media_id=${encodeURIComponent(mediaId)}`,
        { credentials: "include" }
      );
      const data = await safeJson(res);
      setVerifyResult((data ?? { ok: false, error: "verify_failed" }) as VerifyResult);
    } catch {
      setVerifyResult({
        ok: false,
        error: "verify_failed",
        detail: "Could not call verify endpoint.",
      });
    }
  }

  async function syncComments(mediaId: string) {
    setError(null);
    setSyncResult(null);
    setSyncingId(mediaId);

    try {
      const res = await fetch(
        `${BACKEND}/meta/ig/comments/sync?media_id=${encodeURIComponent(mediaId)}`,
        { method: "POST", credentials: "include" }
      );
      const data = (await safeJson(res)) as SyncResult;
      setSyncResult(data);
      await loadStoredComments(mediaId);
      await runVerify(mediaId);
    } catch {
      setSyncResult({
        ok: false,
        error: "sync_failed",
        detail: "Network or server error while syncing comments.",
      });
    } finally {
      setSyncingId(null);
    }
  }

  async function loadCanonical() {
    try {
      const res = await fetch(`${BACKEND}/canonical/list`, { credentials: "include" });
      const data = await safeJson(res);
      setCanonicalPosts(Array.isArray(data) ? data : []);
    } catch {
      setCanonicalPosts([]);
    }
  }

  async function loadCanonicalSummary(canonicalId: number) {
    const res = await fetch(`${BACKEND}/canonical/summary?canonical_post_id=${canonicalId}`, { credentials: "include" });
    const data = await safeJson(res);
    setCanonicalSummary((data ?? { ok: false, error: "summary_failed" }) as CanonicalSummary);
  }

  async function createCanonicalFromIgLink() {
    setCreatingCanon(true);
    setError(null);

    try {
      const url = `${BACKEND}/canonical/create_from_instagram_url?instagram_url=${encodeURIComponent(
        igLink
      )}`;
      const res = await fetch(url, { method: "POST", credentials: "include" });
      const data = await safeJson(res);

      if (!data?.ok) {
        setError("Canonical creation failed. Check backend response.");
        return;
      }

      setIgLink("");
      await loadCanonical();
    } catch {
      setError("Could not create canonical post.");
    } finally {
      setCreatingCanon(false);
    }
  }

  async function trackIgPost(mediaId: string) {
    setTrackingId(mediaId);
    setError(null);

    try {
      const res = await fetch(
        `${BACKEND}/canonical/create_from_instagram_media_id?media_id=${encodeURIComponent(mediaId)}`,
        { method: "POST", credentials: "include" }
      );
      const data = await safeJson(res);

      setLastTrackResult(data);
      setLastTrackAt(new Date().toISOString());

      if (!data?.ok) {
        const detail = data?.detail ? String(data.detail) : "";
        const err = data?.error ? String(data.error) : "track_failed";
        setError(detail ? `${err}: ${detail}` : err);
        return;
      }

      await loadCanonical();

      const cid = findCanonicalIdForIgMediaId(mediaId, canonicalPosts);
      if (cid) {
        setSelectedCanonicalId(cid);
        await loadCanonicalSummary(cid);
      }
    } catch {
      setError("Track failed. Backend not reachable.");
    } finally {
      setTrackingId(null);
    }
  }

  async function refreshAll() {
    await refreshHealth();
    if (igUserId) await loadMedia(igUserId);
    if (selectedMediaId) {
      await loadStoredComments(selectedMediaId);
      await runVerify(selectedMediaId);
      await loadAnalyses(selectedMediaId);
    }
    await loadCanonical();
  }

  useEffect(() => {
    refreshHealth();
    loadIgProfile();
    loadCanonical();
  }, []);

  useEffect(() => {
    if (igUserId) loadMedia(igUserId);
  }, [igUserId]);

  useEffect(() => {
    if (!selectedMediaId) return;

    const cid = findCanonicalIdForIgMediaId(selectedMediaId, canonicalPosts);
    setSelectedCanonicalId(cid);

    if (cid) {
      loadCanonicalSummary(cid).catch(() => {
        setCanonicalSummary({ ok: false, error: "summary_failed" });
      });
    } else {
      setCanonicalSummary(null);
    }

    loadStoredComments(selectedMediaId).catch(() => null);
    loadAnalyses(selectedMediaId).catch(() => null);
  }, [selectedMediaId, canonicalPosts]);

  function onCardKeyDown(e: React.KeyboardEvent<HTMLDivElement>, mediaId: string) {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      setSelectedMediaId(mediaId);
    }
  }

  return (
    <main className="min-h-screen bg-black text-white">
      <div className="mx-auto max-w-6xl px-6 py-10">
        <header className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
          <div>
            <h1 className="text-4xl font-bold tracking-tight">Social Analytics</h1>
            <p className="mt-2 text-white/70">
              Backend status: <span className="text-white">{backendStatus}</span>
            </p>
            <p className="mt-1 text-white/70">
              Instagram professional id: <span className="text-white">{igUserId ?? "loading"}</span>
            </p>
          </div>

          <div className="flex gap-3">
            <Link
              href="/analytics"
              className="futuristic-btn rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
            >
              Global Analytics
            </Link>
            <Link
              href="/help"
              className="futuristic-btn rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
            >
              Help
            </Link>
            <Link
              href="/dashboard"
              className="futuristic-btn rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
            >
              Dashboard
            </Link>
            <Link
              href="/settings"
              className="futuristic-btn rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
            >
              Settings
            </Link>
            <button
              onClick={refreshAll}
              className="futuristic-btn rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
            >
              Refresh
            </button>
          </div>
        </header>

        {error ? (
          <div className="mt-6 rounded-2xl border border-red-500/30 bg-red-500/10 p-4 text-sm text-red-200">
            {error}
          </div>
        ) : null}

        <section className="mt-8 rounded-2xl border border-white/10 bg-white/5 p-6">
          <h2 className="text-lg font-semibold">Add post by Instagram link</h2>
          <p className="mt-1 text-sm text-white/70">
            Paste an Instagram link. The backend will try to match the Facebook post by text and date.
          </p>

          <div className="mt-4 flex flex-col gap-3 sm:flex-row">
            <input
              value={igLink}
              onChange={(e) => setIgLink(e.target.value)}
              className="futuristic-input w-full rounded-xl border border-white/10 bg-black/40 px-4 py-2 outline-none focus:border-white/30"
              placeholder="https://www.instagram.com/p/SHORTCODE/"
            />
            <button
              onClick={createCanonicalFromIgLink}
              disabled={creatingCanon || !igLink.trim()}
              className="rounded-xl bg-white px-5 py-2 text-sm font-semibold text-black disabled:opacity-60"
            >
              {creatingCanon ? "Creating..." : "Create"}
            </button>
          </div>
        </section>

        {/* Navigation */}
        <div className="mb-6 flex items-center justify-between">
          <h1 className="text-3xl font-bold text-white">Social Analytics Dashboard</h1>
          <Link
            href="/analytics"
            className="rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10"
          >
            Global Analytics →
          </Link>
        </div>

        <section className="mt-8 rounded-2xl border border-white/10 bg-white/5 p-6">
          <div className="flex items-center justify-between">
            <h2 className="text-lg font-semibold">Tracked posts</h2>
            <span className="text-sm text-white/60">Total: {canonicalPosts.length}</span>
          </div>

          {lastTrackResult ? (
            <div className="mt-4 rounded-2xl border border-white/10 bg-black/30 p-4 text-sm">
              <div className="text-white/60">Last Track result</div>
              <div className="mt-2 font-mono whitespace-pre-wrap break-words">
                {JSON.stringify(lastTrackResult, null, 2)}
              </div>
              <div className="mt-2 text-xs text-white/60">{fmtDate(lastTrackAt)}</div>
            </div>
          ) : (
            <div className="mt-4 text-sm text-white/70">No Track action yet.</div>
          )}

          <details className="mt-4 rounded-2xl border border-white/10 bg-black/30 p-4">
            <summary className="cursor-pointer select-none text-sm text-white/80">
              Debug list (collapsed by default)
            </summary>

            <div className="mt-4 grid gap-3">
              {canonicalPosts.slice(0, 6).map((p) => (
                <div key={p.id} className="rounded-2xl border border-white/10 bg-white/5 p-4">
                  <div className="flex items-start justify-between gap-4">
                    <div className="min-w-0">
                      <div className="text-sm text-white/60">Canonical id {p.id}</div>
                      <div className="mt-1 font-semibold break-words">{p.title ?? "(no title)"}</div>
                      <div className="mt-2 text-xs text-white/60">{fmtDate(p.created_at)}</div>
                    </div>
                    <div className="shrink-0 text-xs text-white/70">
                      {Array.isArray(p.platform_posts) ? p.platform_posts.length : 0} links
                    </div>
                  </div>

                  {Array.isArray(p.platform_posts) ? (
                    <div className="mt-3 grid gap-2">
                      {p.platform_posts.map((pp: any) => (
                        <div
                          key={`${pp.platform}:${pp.platform_post_id}`}
                          className="rounded-xl border border-white/10 bg-black/30 p-3 text-xs"
                        >
                          <div className="text-white/70">{pp.platform}</div>
                          <div className="mt-1 font-mono break-all">{pp.platform_post_id}</div>
                          <div className="mt-2 text-white/60">
                            Confidence {pp.match_confidence ?? ""} Comments {pp.comment_count_api ?? ""} Reactions{" "}
                            {pp.reaction_count_api ?? ""} Shares {pp.share_count_api ?? ""}
                          </div>
                          {pp.permalink ? (
                            <a
                              className="mt-2 inline-block text-white underline underline-offset-4"
                              href={String(pp.permalink)}
                              target="_blank"
                              rel="noreferrer"
                            >
                              Open
                            </a>
                          ) : null}
                        </div>
                      ))}
                    </div>
                  ) : null}
                </div>
              ))}
            </div>
          </details>
        </section>

        <div className="mt-8 grid gap-6 lg:grid-cols-2">
          <section className="rounded-2xl border border-white/10 bg-white/5 p-6">
            <div className="flex items-center justify-between">
              <h2 className="text-lg font-semibold">Instagram posts</h2>
              <span className="text-sm text-white/60">Loaded: {media.length}</span>
            </div>

            <div className="mt-4 grid gap-3">
              {media.map((m) => {
                const isSelected = m.id === selectedMediaId;
                const title = m.caption ? truncate(m.caption, 90) : "(no caption)";
                const cc = m.comments_count ?? 0;
                const lc = m.like_count ?? 0;

                return (
                  <div
                    key={m.id}
                    role="button"
                    tabIndex={0}
                    onClick={() => setSelectedMediaId(m.id)}
                    onKeyDown={(e) => onCardKeyDown(e, m.id)}
                    className={
                      "futuristic-panel cursor-pointer select-none rounded-2xl border p-4 transition focus:outline-none focus:ring-2 focus:ring-white/20 " +
                      (isSelected
                        ? "border-white/30 bg-white/10"
                        : "border-white/10 bg-white/5 hover:bg-white/10")
                    }
                  >
                    <div className="flex items-start justify-between gap-4">
                      <div className="min-w-0">
                        <div className="text-sm text-white/60">{m.media_type ?? "MEDIA"}</div>
                        <div className="mt-1 font-semibold break-words">{title}</div>
                        <div className="mt-2 text-xs text-white/60">
                          Likes {lc} | Comments {cc}
                        </div>
                      </div>

                      <div className="flex flex-col items-end gap-2 shrink-0">
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            trackIgPost(m.id);
                          }}
                          disabled={trackingId === m.id}
                          className="rounded-lg border border-white/15 bg-white/5 px-3 py-1 text-xs hover:bg-white/10 disabled:opacity-60"
                        >
                          {trackingId === m.id ? "Tracking..." : "Track"}
                        </button>

                        <div className="text-xs text-white/60">{fmtDate(m.timestamp)}</div>
                      </div>
                    </div>
                  </div>
                );
              })}

              {media.length === 0 ? (
                <div className="rounded-2xl border border-white/10 bg-white/5 p-8 text-center text-white/70">
                  No media loaded. If Meta is connected, try Refresh.
                </div>
              ) : null}
            </div>
          </section>

          <section className="rounded-2xl border border-white/10 bg-white/5 p-6">
            <div className="flex items-center justify-between gap-4">
              <div>
                <h2 className="text-lg font-semibold">Selected post</h2>
                <p className="mt-1 text-sm text-white/70">
                  Sync comments, browse stored data, and see cross platform totals.
                </p>
              </div>

              <button
                disabled={!selectedMediaId || syncingId === selectedMediaId}
                onClick={() => selectedMediaId && syncComments(selectedMediaId)}
                className="rounded-xl bg-white px-5 py-2 text-sm font-semibold text-black disabled:opacity-60"
              >
                {syncingId === selectedMediaId ? "Syncing..." : "Sync comments"}
              </button>
            </div>

            {selected ? (
              <div className="mt-5 rounded-2xl border border-white/10 bg-black/30 p-4">
                <div className="text-sm text-white/60">Media id</div>
                <div className="mt-1 font-mono text-sm break-all">{selected.id}</div>

                <div className="mt-3 flex flex-wrap gap-4">
                  {selected.permalink ? (
                    <a
                      className="futuristic-link text-sm text-white underline underline-offset-4"
                      href={selected.permalink}
                      target="_blank"
                      rel="noreferrer"
                    >
                      Open on Instagram
                    </a>
                  ) : null}

                  {fbPermalink ? (
                    <a
                      className="futuristic-link text-sm text-white underline underline-offset-4"
                      href={fbPermalink}
                      target="_blank"
                      rel="noreferrer"
                    >
                      Open on Facebook
                    </a>
                  ) : null}
                </div>

                <div className="mt-4 grid grid-cols-2 gap-3 text-sm">
                  <MetricCard label="API comments" value={selected.comments_count ?? 0} />
                  <MetricCard
                    label="Stored comments total"
                    value={
                      verifyResult && "stored_total" in verifyResult
                        ? verifyResult.stored_total
                        : comments.length
                    }
                  />
                </div>

                {coverage ? (
                  <div className="mt-3 text-sm text-white/70">
                    Coverage: {coverage.storedTotal} of {coverage.apiCount} ({coverage.pct}%)
                    <div className="mt-2 text-xs text-white/60">
                      Hidden comments and restricted users can cause the Instagram app UI count to be higher than the API.
                    </div>
                  </div>
                ) : null}

                {syncResult ? (
                  <div className="mt-4 rounded-xl border border-white/10 bg-white/5 p-3 text-sm">
                    {"ok" in syncResult && syncResult.ok ? (
                      <div>
                        <div className="font-semibold">Last sync result</div>
                        <div className="mt-1 text-white/70">
                          Total {syncResult.saved_total} | Top level {syncResult.saved_top_level} | Replies{" "}
                          {syncResult.saved_replies}
                        </div>
                      </div>
                    ) : (
                      <div>
                        <div className="font-semibold">Last sync failed</div>
                        <div className="mt-1 text-white/70">
                          {"detail" in syncResult ? syncResult.detail : "Unknown error"}
                        </div>
                      </div>
                    )}
                  </div>
                ) : null}
              </div>
            ) : (
              <div className="mt-5 rounded-2xl border border-white/10 bg-black/30 p-6 text-white/70">
                Select a post on the left.
              </div>
            )}

            {selectedCanonicalId ? (
              <div className="mt-4 rounded-2xl border border-white/10 bg-black/30 p-4">
                <div className="text-sm text-white/60">Cross platform totals</div>

                {canonicalSummary && "ok" in canonicalSummary && canonicalSummary.ok ? (
                  <>
                    <div className="mt-3 grid grid-cols-2 gap-3 text-sm">
                      <MetricCard label="Total comments stored" value={canonicalSummary.totals.comments_stored} />
                      <MetricCard label="Total comments API" value={canonicalSummary.totals.comments_api} />
                      <MetricCard label="Total reactions API" value={canonicalSummary.totals.reactions_api} />
                      <MetricCard label="Total shares API" value={canonicalSummary.totals.shares_api} />
                    </div>

                    <div className="mt-4 grid gap-3 sm:grid-cols-2">
                      {canonicalSummary.platforms.instagram ? (
                        <PlatformRow
                          platform="Instagram"
                          permalink={canonicalSummary.platforms.instagram.permalink}
                          commentCountApi={canonicalSummary.platforms.instagram.comment_count_api}
                          reactionCountApi={canonicalSummary.platforms.instagram.reaction_count_api}
                          shareCountApi={canonicalSummary.platforms.instagram.share_count_api}
                          viewCountApi={canonicalSummary.platforms.instagram.view_count_api}
                          commentsStored={canonicalSummary.platforms.instagram.comments_stored}
                        />
                      ) : null}

                      {canonicalSummary.platforms.facebook ? (
                        <div className="futuristic-panel rounded-2xl border border-white/10 bg-white/5 p-4">
                          <div className="flex items-start justify-between gap-4">
                            <div className="min-w-0 flex-1">
                              <div className="flex items-center gap-2">
                                <div className="text-sm font-semibold">Facebook</div>
                                {canonicalSummary.platforms.facebook.match_confidence != null ? (
                                  <span className="text-xs text-white/60">
                                    Match {canonicalSummary.platforms.facebook.match_confidence}%
                                  </span>
                                ) : (
                                  <span className="text-xs text-white/60">Manual match</span>
                                )}
                              </div>
                              {canonicalSummary.platforms.facebook.comments_stored === 0 && 
                               (canonicalSummary.platforms.facebook.comment_count_api || 0) > 0 ? (
                                <div className="mt-2 text-xs text-yellow-400">
                                  ⚠️ Comments not synced (API shows {canonicalSummary.platforms.facebook.comment_count_api} comments)
                                </div>
                              ) : null}
                              {canonicalSummary.platforms.facebook.permalink ? (
                                <a
                                  className="mt-2 inline-block text-sm text-white underline underline-offset-4"
                                  href={String(canonicalSummary.platforms.facebook.permalink)}
                                  target="_blank"
                                  rel="noreferrer"
                                >
                                  Open on Facebook
                                </a>
                              ) : (
                                <div className="mt-2 text-sm text-white/60">No link available</div>
                              )}
                              {editingFacebookPost ? (
                                <div className="mt-3 space-y-2">
                                  <input
                                    value={facebookPostInput}
                                    onChange={(e) => setFacebookPostInput(e.target.value)}
                                    className="futuristic-input w-full rounded-xl border border-white/10 bg-black/40 px-3 py-2 text-sm outline-none focus:border-white/30"
                                    placeholder="Facebook post URL or numeric ID (e.g., https://www.facebook.com/... or 123456789)"
                                  />
                                  <div className="text-xs text-white/60">
                                    If the URL contains a pfbid and conversion fails, you can also provide just the numeric post ID directly.
                                  </div>
                                  {error && (
                                    <div className={`mt-2 rounded-lg border px-3 py-2 text-xs ${
                                      error.startsWith("✅") 
                                        ? "border-green-500/30 bg-green-500/10 text-green-200" 
                                        : error.startsWith("⚠️")
                                        ? "border-yellow-500/30 bg-yellow-500/10 text-yellow-200"
                                        : "border-red-500/30 bg-red-500/10 text-red-200"
                                    }`}>
                                      <div className="whitespace-pre-line">{error}</div>
                                    </div>
                                  )}
                                  <div className="flex gap-2">
                                    <button
                                      onClick={async () => {
                                        if (!selectedCanonicalId || !facebookPostInput.trim()) return;
                                        setUpdatingFacebookPost(true);
                                        setError(null);
                                        try {
                                          const input = facebookPostInput.trim();
                                          const isUrl = input.includes("facebook.com");
                                          const isNumericId = /^\d+$/.test(input);
                                          
                                          const params = new URLSearchParams({
                                            canonical_post_id: String(selectedCanonicalId),
                                          });
                                          
                                          if (isUrl) {
                                            params.append("facebook_url", input);
                                          } else if (isNumericId) {
                                            // If it's a numeric ID, use it directly (avoids pfbid conversion issues)
                                            params.append("facebook_post_id", input);
                                          } else {
                                            // Assume it's a post ID (could be pfbid or numeric)
                                            params.append("facebook_post_id", input);
                                          }
                                          const res = await fetch(`${BACKEND}/canonical/update_facebook_post?${params}`, {
                                            method: "POST",
                                            credentials: "include",
                                          });
                                          
                                          if (!res.ok) {
                                            const errorText = await res.text();
                                            setError(`HTTP ${res.status}: ${errorText || "Unknown error"}`);
                                            return;
                                          }
                                          
                                          const data = await safeJson(res);
                                          
                                          if (!data) {
                                            setError("No response from server. Check backend connection.");
                                            return;
                                          }
                                          
                                          if (data?.ok) {
                                            setEditingFacebookPost(false);
                                            setFacebookPostInput("");
                                            // Show success message briefly, then clear
                                            const successMsg = data?.was_converted 
                                              ? `✅ Facebook post updated! Converted pfbid to numeric ID: ${data.facebook_post_id}`
                                              : `✅ Facebook post updated! Post ID: ${data.facebook_post_id}`;
                                            setError(successMsg);
                                            setTimeout(() => setError(null), 3000);
                                            
                                            // Show warning if comments sync failed
                                            if (data?.sync_warning) {
                                              setTimeout(() => {
                                                setError(`⚠️ ${data.sync_warning}. You may need to manually sync comments.`);
                                              }, 3500);
                                            } else if (data?.sync_result && !data.sync_result.ok) {
                                              setTimeout(() => {
                                                setError(`⚠️ Comments sync failed: ${data.sync_result.error || "Unknown error"}. You may need to manually sync comments.`);
                                              }, 3500);
                                            }
                                            
                                            // Refresh the summary to show updated metrics
                                            await loadCanonicalSummary(selectedCanonicalId);
                                            await loadCanonical();
                                            // Also refresh comments if we have a selected media
                                            if (selectedMediaId) {
                                              await loadStoredComments(selectedMediaId);
                                            }
                                          } else {
                                            setError(
                                              `❌ Failed to update Facebook post: ${data?.error || "Unknown error"}${data?.detail ? ` - ${data.detail}` : ""}${data?.hint ? `\n\n💡 ${data.hint}` : ""}`
                                            );
                                          }
                                        } catch (err) {
                                          setError("Failed to update Facebook post. Check backend connection.");
                                        } finally {
                                          setUpdatingFacebookPost(false);
                                        }
                                      }}
                                      disabled={updatingFacebookPost || !facebookPostInput.trim()}
                                      className="rounded-lg bg-white px-3 py-1.5 text-xs font-semibold text-black disabled:opacity-60"
                                    >
                                      {updatingFacebookPost ? "Updating..." : "Update"}
                                    </button>
                                    <button
                                      onClick={() => {
                                        setEditingFacebookPost(false);
                                        setFacebookPostInput("");
                                        setError(null);
                                      }}
                                      disabled={updatingFacebookPost}
                                      className="rounded-lg border border-white/15 bg-white/5 px-3 py-1.5 text-xs hover:bg-white/10 disabled:opacity-60"
                                    >
                                      Cancel
                                    </button>
                                  </div>
                                </div>
                              ) : (
                                <div className="mt-3 text-sm text-white/70">
                                  Stored comments {toInt(canonicalSummary.platforms.facebook.comments_stored)} <br />
                                  API comments {toInt(canonicalSummary.platforms.facebook.comment_count_api)} <br />
                                  API reactions {toInt(canonicalSummary.platforms.facebook.reaction_count_api)} <br />
                                  API shares {toInt(canonicalSummary.platforms.facebook.share_count_api)} <br />
                                  API views {toInt(canonicalSummary.platforms.facebook.view_count_api)}
                                </div>
                              )}
                            </div>
                            {!editingFacebookPost && (
                              <div className="flex gap-2">
                                <button
                                  onClick={() => {
                                    setEditingFacebookPost(true);
                                    setFacebookPostInput(canonicalSummary.platforms.facebook.permalink || "");
                                  }}
                                  className="shrink-0 rounded-lg border border-white/15 bg-white/5 px-3 py-1.5 text-xs hover:bg-white/10"
                                  title="Update Facebook post ID if the match is incorrect"
                                >
                                  Edit
                                </button>
                                {canonicalSummary.platforms.facebook.platform_post_id?.startsWith("pfbid") ? (
                                  <button
                                    onClick={async () => {
                                      const numericId = prompt(
                                        "The stored post ID is a pfbid which causes errors.\n\n" +
                                        "Please enter the numeric Facebook post ID.\n\n" +
                                        "You can find it by:\n" +
                                        "1. Opening the post on Facebook\n" +
                                        "2. Using Facebook Graph API Explorer\n" +
                                        "3. Or inspecting the post's API response\n\n" +
                                        "Enter numeric post ID:"
                                      );
                                      if (!numericId || !numericId.trim()) return;
                                      
                                      setUpdatingFacebookPost(true);
                                      setError(null);
                                      try {
                                        const params = new URLSearchParams({
                                          canonical_post_id: String(selectedCanonicalId),
                                          numeric_post_id: numericId.trim(),
                                        });
const res = await fetch(`${BACKEND}/canonical/fix_facebook_pfbid?${params}`, {
                                        method: "POST",
                                        credentials: "include",
                                        });
                                        const data = await safeJson(res);
                                        if (data?.ok) {
                                          await loadCanonicalSummary(selectedCanonicalId);
                                          await loadCanonical();
                                        } else {
                                          setError(
                                            `Failed to fix pfbid: ${data?.error || "Unknown error"}${data?.detail ? ` - ${data.detail}` : ""}${data?.hint ? ` (${data.hint})` : ""}`
                                          );
                                        }
                                      } catch (err) {
                                        setError("Failed to fix pfbid. Check backend connection.");
                                      } finally {
                                        setUpdatingFacebookPost(false);
                                      }
                                    }}
                                    disabled={updatingFacebookPost}
                                    className="shrink-0 rounded-lg border border-yellow-500/30 bg-yellow-500/10 px-3 py-1.5 text-xs text-yellow-200 hover:bg-yellow-500/20 disabled:opacity-60"
                                    title="Fix pfbid by providing numeric post ID"
                                  >
                                    Fix pfbid
                                  </button>
                                ) : null}
                              </div>
                            )}
                          </div>
                        </div>
                      ) : null}
                    </div>

                    <div className="mt-3 text-xs text-white/60">
                      Shares are shown when the backend stores share_count_api for the platform post.
                    </div>
                  </>
                ) : (
                  <div className="mt-2 text-sm text-white/70">Summary not available yet.</div>
                )}
              </div>
            ) : (
              <div className="mt-4 rounded-2xl border border-white/10 bg-black/30 p-4 text-sm text-white/70">
                Not tracked yet. Track this post to see cross platform totals.
              </div>
            )}

            <div className="mt-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
              <div>
                <h3 className="text-lg font-semibold">Stored comments</h3>
                <div className="mt-1 text-sm text-white/60">Loaded: {comments.length} | Analysed: {Object.keys(analyses).length}</div>
              </div>

              <div className="flex gap-3">
                <button
                  disabled={!selectedMediaId || comments.length === 0 || analyzing}
                  onClick={() => selectedMediaId && analyzeWithOpenAI(selectedMediaId, false)}
                  className="rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm hover:bg-white/10 disabled:opacity-60"
                  title="Analyze only comments that haven't been processed yet"
                >
                  {analyzing ? "Analysing..." : "Analyse New Comments"}
                </button>
                <button
                  disabled={!selectedMediaId || comments.length === 0 || analyzing}
                  onClick={() => selectedMediaId && analyzeWithOpenAI(selectedMediaId, true)}
                  className="rounded-xl border border-orange-500/30 bg-orange-500/10 px-4 py-2 text-sm text-orange-200 hover:bg-orange-500/20 disabled:opacity-60"
                  title="Reprocess all comments (including already analyzed ones)"
                >
                  {analyzing ? "Reprocessing..." : "Reprocess All Comments"}
                </button>
              </div>
            </div>

            {lastAnalyzeResult ? (
              <div className="mt-4 rounded-2xl border border-white/10 bg-black/30 p-4 text-sm">
                <div className="text-white/60">Last OpenAI run</div>
                <div className="mt-2 font-mono whitespace-pre-wrap break-words">
                  {JSON.stringify(lastAnalyzeResult, null, 2)}
                </div>
              </div>
            ) : null}

            <div className="mt-4 max-h-[520px] overflow-auto rounded-2xl border border-white/10">
              {comments.length === 0 ? (
                <div className="p-6 text-center text-white/70">
                  No comments stored for this post yet. Click Sync comments.
                </div>
              ) : (
                <div className="divide-y divide-white/10">
                  {comments.map((c) => {
                    const a = analyses[c.comment_id];
                    const topics = Array.isArray(a?.topics) ? a!.topics!.map((t) => t.label).slice(0, 3) : [];
                    const sentiment = a?.sentiment_label ? String(a.sentiment_label) : null;
                    const intent = a?.intent_type ? String(a.intent_type) : null;
                    const tox = a?.toxicity_is_toxic ? "toxic" : null;

                    return (
                    <div key={c.comment_id} className="p-4">
                      <div className="flex items-start justify-between gap-4">
                        <div className="text-sm">
                          <span className="font-semibold">{c.username ?? "unknown"}</span>
                          <span className="text-white/60"> | Likes {c.like_count ?? 0}</span>
                        </div>
                        <div className="text-xs text-white/60">{fmtDate(c.timestamp)}</div>
                      </div>

                      {a ? (
                        <div className="mt-2 flex flex-wrap gap-2 text-xs">
                          {sentiment ? (
                            <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                              Sentiment {sentiment}{a.sentiment_score != null ? ` ${a.sentiment_score}%` : ""}
                            </span>
                          ) : null}
                          {intent ? (
                            <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                              Intent {intent}{a.intent_confidence != null ? ` ${a.intent_confidence}%` : ""}
                            </span>
                          ) : null}
                          {a.emotion_primary ? (
                            <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                              Emotion {String(a.emotion_primary)}{a.emotion_confidence != null ? ` ${a.emotion_confidence}%` : ""}
                            </span>
                          ) : null}
                          {topics.length ? (
                            <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                              Topics {topics.join(", ")}
                            </span>
                          ) : null}
                          {tox ? (
                            <span className="rounded-full border border-red-500/30 bg-red-500/10 px-2 py-1 text-red-200">
                              Toxic
                            </span>
                          ) : null}
                        </div>
                      ) : (
                        <div className="mt-2 text-xs text-white/50">No OpenAI analysis yet</div>
                      )}

                      <div className="mt-2 text-sm text-white/80 whitespace-pre-wrap">{c.text ?? ""}</div>
                    </div>
                  );
                  })}
                </div>
              )}
            </div>
          </section>
        </div>

        <div className="mt-10 rounded-2xl border border-white/10 bg-white/5 p-6 text-sm text-white/70">
          Next steps: aggregate analyses across Instagram and Facebook, compute per topic volume, per sentiment distribution, and build a dashboard view per canonical post.
        </div>
      </div>
    </main>
  );
}
