"use client";

import { useState, useRef, useEffect } from "react";
import { createPortal } from "react-dom";
import { cn } from "@/lib/utils";

// ============================================================================
// Types - mirrors the Skeptic API response
// ============================================================================

type SourceTier = 0 | 1 | 2 | 3 | 4 | 5;
type ConflictStatus = "unanimous" | "agreed" | "contested";
type SourceStatus = "active" | "deprecated" | "quarantined";

interface AgentSummary {
  agentId: string; // hex, first 8 chars for display
  trustScore: number; // 0.0 - 1.0
}

interface SourceInfo {
  hash: string;
  label: string;
  tier: SourceTier;
  tierLabel: string;
  url?: string;
  status: SourceStatus;
  visualHash?: string;
}

interface ClaimSummary {
  value: string;
  valueType: "text" | "number" | "boolean" | "reference";
  weightShare: number; // 0.0 - 1.0
  assertionCount: number;
  representativeHash: string;
  source: SourceInfo;
  supportingAgents: AgentSummary[];
  timestamp?: number; // Unix timestamp of representative assertion
}

interface ClaimData {
  // Resolution metadata
  status: ConflictStatus;
  conflictScore: number; // 0.0 - 1.0 (Shannon entropy)
  candidatesCount: number;
  computedAt: number; // Unix timestamp

  // All competing claims
  claims: ClaimSummary[];

  // Optional note
  note?: string;
}

interface ClaimProps {
  children: React.ReactNode;
  data?: ClaimData;
  // Legacy props for simple claims (backwards compatible)
  sources?: Array<{ label: string; tier: SourceTier; url?: string }>;
  confidence?: number;
  conflictStatus?: ConflictStatus;
  note?: string;
}

// ============================================================================
// Constants
// ============================================================================

const tierLabels: Record<SourceTier, string> = {
  0: "Regulatory",
  1: "Clinical",
  2: "Observational",
  3: "Expert",
  4: "Community",
  5: "Anecdotal",
};

const tierColors: Record<SourceTier, string> = {
  0: "bg-emerald-500/20 text-emerald-700 dark:text-emerald-300 border-emerald-500/30",
  1: "bg-blue-500/20 text-blue-700 dark:text-blue-300 border-blue-500/30",
  2: "bg-cyan-500/20 text-cyan-700 dark:text-cyan-300 border-cyan-500/30",
  3: "bg-amber-500/20 text-amber-700 dark:text-amber-300 border-amber-500/30",
  4: "bg-orange-500/20 text-orange-700 dark:text-orange-300 border-orange-500/30",
  5: "bg-red-500/20 text-red-700 dark:text-red-300 border-red-500/30",
};

const tierBgColors: Record<SourceTier, string> = {
  0: "bg-emerald-500",
  1: "bg-blue-500",
  2: "bg-cyan-500",
  3: "bg-amber-500",
  4: "bg-orange-500",
  5: "bg-red-500",
};

const statusColors: Record<SourceStatus, string> = {
  active: "text-emerald-600 dark:text-emerald-400",
  deprecated: "text-amber-600 dark:text-amber-400",
  quarantined: "text-red-600 dark:text-red-400",
};

const statusIcons: Record<SourceStatus, string> = {
  active: "●",
  deprecated: "◐",
  quarantined: "⚠",
};

const conflictColors: Record<ConflictStatus, string> = {
  unanimous: "text-emerald-600 dark:text-emerald-400",
  agreed: "text-amber-600 dark:text-amber-400",
  contested: "text-red-600 dark:text-red-400",
};

const conflictBgColors: Record<ConflictStatus, string> = {
  unanimous: "bg-emerald-500",
  agreed: "bg-amber-500",
  contested: "bg-red-500",
};

const conflictLabels: Record<ConflictStatus, string> = {
  unanimous: "Unanimous",
  agreed: "Mostly Agreed",
  contested: "Contested",
};

// ============================================================================
// Helper Components
// ============================================================================

function TierBadge({ tier, size = "sm" }: { tier: SourceTier; size?: "sm" | "xs" }) {
  return (
    <span
      className={cn(
        "font-mono font-semibold rounded border",
        tierColors[tier],
        size === "sm" ? "px-1.5 py-0.5 text-xs" : "px-1 py-0.5 text-[10px]"
      )}
    >
      T{tier}
    </span>
  );
}

function TrustBar({ score, size = "md" }: { score: number; size?: "sm" | "md" }) {
  const percent = Math.round(score * 100);
  return (
    <div className="flex items-center gap-2">
      <div
        className={cn(
          "bg-muted rounded-full overflow-hidden flex-1",
          size === "sm" ? "h-1" : "h-1.5"
        )}
      >
        <div
          className={cn(
            "h-full rounded-full transition-all",
            score >= 0.7
              ? "bg-emerald-500"
              : score >= 0.4
              ? "bg-amber-500"
              : "bg-red-500"
          )}
          style={{ width: `${percent}%` }}
        />
      </div>
      <span className="text-xs font-mono text-muted-foreground w-8">
        {score.toFixed(2)}
      </span>
    </div>
  );
}

function ConflictBar({ score, status }: { score: number; status: ConflictStatus }) {
  const percent = Math.round(score * 100);
  return (
    <div className="space-y-1">
      <div className="flex items-center justify-between text-xs">
        <span className="text-muted-foreground">Conflict Score</span>
        <span className={cn("font-medium", conflictColors[status])}>
          {percent}% entropy
        </span>
      </div>
      <div className="h-2 bg-muted rounded-full overflow-hidden">
        <div
          className={cn("h-full rounded-full transition-all", conflictBgColors[status])}
          style={{ width: `${percent}%` }}
        />
      </div>
      <div className="flex justify-between text-[10px] text-muted-foreground">
        <span>Unanimous</span>
        <span>Chaos</span>
      </div>
    </div>
  );
}

function WeightBar({
  share,
  tier,
  isLeading,
}: {
  share: number;
  tier: SourceTier;
  isLeading: boolean;
}) {
  const percent = Math.round(share * 100);
  return (
    <div className="flex items-center gap-2">
      <div className="h-3 bg-muted rounded-full overflow-hidden flex-1">
        <div
          className={cn(
            "h-full rounded-full transition-all",
            tierBgColors[tier],
            isLeading ? "opacity-100" : "opacity-60"
          )}
          style={{ width: `${percent}%` }}
        />
      </div>
      <span className="text-xs font-mono text-muted-foreground w-10 text-right">
        {percent}%
      </span>
    </div>
  );
}

function HashDisplay({
  hash,
  label,
  copyable = true,
}: {
  hash: string;
  label: string;
  copyable?: boolean;
}) {
  const [copied, setCopied] = useState(false);
  const short = hash.slice(0, 8) + "..." + hash.slice(-4);

  const handleCopy = () => {
    navigator.clipboard.writeText(hash);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };

  return (
    <div className="flex items-center gap-2 text-xs">
      <span className="text-muted-foreground">{label}:</span>
      <code className="font-mono bg-muted px-1.5 py-0.5 rounded text-[10px]">
        {short}
      </code>
      {copyable && (
        <button
          onClick={handleCopy}
          className="text-muted-foreground hover:text-foreground transition-colors"
        >
          {copied ? "✓" : "⧉"}
        </button>
      )}
    </div>
  );
}

function TimeAgo({ timestamp }: { timestamp: number }) {
  const now = Date.now();
  const diff = now - timestamp;
  const days = Math.floor(diff / (1000 * 60 * 60 * 24));
  const months = Math.floor(days / 30);

  let text: string;
  if (months > 0) {
    text = `${months}mo ago`;
  } else if (days > 0) {
    text = `${days}d ago`;
  } else {
    text = "today";
  }

  return (
    <span className="text-xs text-muted-foreground" title={new Date(timestamp).toISOString()}>
      {text}
    </span>
  );
}

// ============================================================================
// Tab Components
// ============================================================================

type TabId = "summary" | "claims" | "provenance" | "raw";

function TabButton({
  active,
  onClick,
  children,
}: {
  active: boolean;
  onClick: () => void;
  children: React.ReactNode;
}) {
  return (
    <button
      onClick={onClick}
      className={cn(
        "px-3 py-1.5 text-xs font-medium rounded-t transition-colors",
        active
          ? "bg-card text-foreground border-t border-l border-r border-border -mb-px"
          : "text-muted-foreground hover:text-foreground"
      )}
    >
      {children}
    </button>
  );
}

// ============================================================================
// Main Component
// ============================================================================

export function Claim({
  children,
  data,
  sources,
  confidence,
  conflictStatus,
  note,
}: ClaimProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [isExpanded, setIsExpanded] = useState(false);
  const [position, setPosition] = useState<"above" | "below">("below");
  const [popoverStyle, setPopoverStyle] = useState<React.CSSProperties>({});
  const [activeTab, setActiveTab] = useState<TabId>("summary");
  const [expandedClaim, setExpandedClaim] = useState<number | null>(null);
  const [mounted, setMounted] = useState(false);
  const triggerRef = useRef<HTMLSpanElement>(null);
  const popoverRef = useRef<HTMLDivElement>(null);

  // For portal - need to wait for mount
  useEffect(() => {
    setMounted(true);
  }, []);

  // Convert legacy props to ClaimData if needed
  const claimData: ClaimData | null = data
    ? data
    : sources && sources.length > 0
    ? {
        status: conflictStatus || "agreed",
        conflictScore: conflictStatus === "contested" ? 0.6 : conflictStatus === "agreed" ? 0.25 : 0.05,
        candidatesCount: sources.length,
        computedAt: Date.now(),
        claims: sources.map((s, i) => ({
          value: "Legacy claim",
          valueType: "text" as const,
          weightShare: 1 / sources.length,
          assertionCount: 1,
          representativeHash: `legacy${i}`,
          source: {
            hash: `source${i}`,
            label: s.label,
            tier: s.tier,
            tierLabel: tierLabels[s.tier],
            url: s.url,
            status: "active" as const,
          },
          supportingAgents: [],
        })),
        note,
      }
    : null;

  // Calculate position when opening
  useEffect(() => {
    if (isOpen && triggerRef.current) {
      const rect = triggerRef.current.getBoundingClientRect();
      const spaceBelow = window.innerHeight - rect.bottom;
      const spaceAbove = rect.top;
      const showAbove = spaceBelow < 450 && spaceAbove > spaceBelow;
      setPosition(showAbove ? "above" : "below");

      // Calculate fixed position for portal
      setPopoverStyle({
        position: "fixed",
        left: `${rect.left}px`,
        top: showAbove ? `${rect.top - 8}px` : `${rect.bottom + 8}px`,
        transform: showAbove ? "translateY(-100%)" : "translateY(0)",
        zIndex: 9999,
      });
    }
  }, [isOpen]);

  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (
        popoverRef.current &&
        !popoverRef.current.contains(event.target as Node) &&
        triggerRef.current &&
        !triggerRef.current.contains(event.target as Node)
      ) {
        setIsOpen(false);
        setIsExpanded(false);
        setActiveTab("summary");
        setExpandedClaim(null);
      }
    }

    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
      return () => document.removeEventListener("mousedown", handleClickOutside);
    }
  }, [isOpen]);

  // Escape key to close
  useEffect(() => {
    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === "Escape" && isOpen) {
        setIsOpen(false);
        setIsExpanded(false);
        setActiveTab("summary");
        setExpandedClaim(null);
      }
    }

    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [isOpen]);

  const hasRichData = claimData && claimData.claims.length > 0;
  const leadingClaim = hasRichData ? claimData.claims[0] : null;

  return (
    <span className="relative inline">
      <span
        ref={triggerRef}
        onClick={() => setIsOpen(!isOpen)}
        className={cn(
          "border-b-2 border-dotted cursor-pointer transition-colors",
          claimData?.status === "contested"
            ? "border-red-500/60 hover:border-red-500 hover:bg-red-500/10"
            : claimData?.status === "agreed"
            ? "border-amber-500/60 hover:border-amber-500 hover:bg-amber-500/10"
            : "border-emerald-500/60 hover:border-emerald-500 hover:bg-emerald-500/10"
        )}
      >
        {children}
      </span>

      {isOpen && claimData && mounted && createPortal(
        <>
          {/* Backdrop for expanded modal */}
          {isExpanded && (
            <div
              className="fixed inset-0 bg-black/50 z-[9998]"
              onClick={() => {
                setIsOpen(false);
                setIsExpanded(false);
                setActiveTab("summary");
                setExpandedClaim(null);
              }}
            />
          )}
          <div
            ref={popoverRef}
            style={isExpanded ? undefined : popoverStyle}
            className={cn(
              "bg-card border border-border rounded-lg shadow-xl",
              isExpanded
                ? "fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-[800px] max-h-[80vh] z-[9999] flex flex-col"
                : "w-[420px]"
            )}
          >
            {/* Header */}
            <div className="px-4 py-3 border-b border-border bg-muted/30 rounded-t-lg flex-shrink-0">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
                    Claim Analysis
                  </span>
                  <span className="text-[10px] text-muted-foreground">
                    via SkepticLens
                  </span>
                </div>
                <div className="flex items-center gap-2">
                  <span
                    className={cn(
                      "text-xs font-semibold px-2 py-0.5 rounded",
                      claimData.status === "contested"
                        ? "bg-red-500/20 text-red-700 dark:text-red-300"
                        : claimData.status === "agreed"
                        ? "bg-amber-500/20 text-amber-700 dark:text-amber-300"
                        : "bg-emerald-500/20 text-emerald-700 dark:text-emerald-300"
                    )}
                  >
                    {conflictLabels[claimData.status]}
                  </span>
                  <button
                    onClick={() => setIsExpanded(!isExpanded)}
                    className="p-1 text-muted-foreground hover:text-foreground transition-colors rounded hover:bg-muted"
                    title={isExpanded ? "Collapse" : "Expand"}
                  >
                    {isExpanded ? "⤡" : "⤢"}
                  </button>
                </div>
              </div>
            </div>

          {/* Tabs */}
          <div className="flex gap-1 px-4 pt-2 border-b border-border bg-muted/20 flex-shrink-0">
            <TabButton active={activeTab === "summary"} onClick={() => setActiveTab("summary")}>
              Summary
            </TabButton>
            <TabButton active={activeTab === "claims"} onClick={() => setActiveTab("claims")}>
              Claims ({claimData.claims.length})
            </TabButton>
            <TabButton active={activeTab === "provenance"} onClick={() => setActiveTab("provenance")}>
              Provenance
            </TabButton>
            <TabButton active={activeTab === "raw"} onClick={() => setActiveTab("raw")}>
              Raw
            </TabButton>
          </div>

          {/* Tab Content */}
          <div className={cn(
            "p-4 overflow-y-auto",
            isExpanded ? "flex-1 min-h-0" : "max-h-[400px]"
          )}>
            {/* ============ SUMMARY TAB ============ */}
            {activeTab === "summary" && (
              <div className="space-y-4">
                {/* Conflict score */}
                <ConflictBar score={claimData.conflictScore} status={claimData.status} />

                {/* Quick stats */}
                <div className="flex gap-4 text-xs">
                  <div className="flex items-center gap-1.5">
                    <span className="text-muted-foreground">Assertions:</span>
                    <span className="font-semibold">{claimData.candidatesCount}</span>
                  </div>
                  <div className="flex items-center gap-1.5">
                    <span className="text-muted-foreground">Distinct claims:</span>
                    <span className="font-semibold">{claimData.claims.length}</span>
                  </div>
                </div>

                {/* Claim distribution mini-view */}
                <div className="space-y-2">
                  <div className="text-xs font-medium text-muted-foreground">
                    Weight Distribution
                  </div>
                  {claimData.claims.slice(0, 3).map((claim, i) => (
                    <div key={i} className="space-y-1">
                      <div className="flex items-center gap-2">
                        <TierBadge tier={claim.source.tier} size="xs" />
                        <span className="text-xs truncate flex-1" title={claim.value}>
                          &ldquo;{claim.value.length > 30 ? claim.value.slice(0, 30) + "..." : claim.value}&rdquo;
                        </span>
                      </div>
                      <WeightBar share={claim.weightShare} tier={claim.source.tier} isLeading={i === 0} />
                    </div>
                  ))}
                  {claimData.claims.length > 3 && (
                    <button
                      onClick={() => setActiveTab("claims")}
                      className="text-xs text-muted-foreground hover:text-foreground"
                    >
                      +{claimData.claims.length - 3} more claims →
                    </button>
                  )}
                </div>

                {/* Leading source */}
                {leadingClaim && (
                  <div className="border-t border-border pt-3 space-y-2">
                    <div className="text-xs font-medium text-muted-foreground">
                      Leading Source
                    </div>
                    <div className="flex items-start gap-2">
                      <TierBadge tier={leadingClaim.source.tier} />
                      <div className="flex-1 min-w-0">
                        <div className="text-sm font-medium truncate">
                          {leadingClaim.source.label}
                        </div>
                        <div className="flex items-center gap-2 mt-0.5">
                          <span className={cn("text-xs", statusColors[leadingClaim.source.status])}>
                            {statusIcons[leadingClaim.source.status]} {leadingClaim.source.status}
                          </span>
                          {leadingClaim.timestamp && (
                            <TimeAgo timestamp={leadingClaim.timestamp} />
                          )}
                        </div>
                      </div>
                    </div>
                    {leadingClaim.source.url && (
                      <a
                        href={leadingClaim.source.url}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="text-xs text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1"
                      >
                        View source ↗
                      </a>
                    )}
                  </div>
                )}

                {/* Note */}
                {claimData.note && (
                  <div className="text-xs text-muted-foreground border-t border-border pt-3 italic">
                    {claimData.note}
                  </div>
                )}
              </div>
            )}

            {/* ============ CLAIMS TAB ============ */}
            {activeTab === "claims" && (
              <div className="space-y-3">
                {claimData.claims.map((claim, i) => (
                  <div
                    key={i}
                    className={cn(
                      "border rounded-lg transition-all",
                      expandedClaim === i
                        ? "border-foreground/20 bg-muted/30"
                        : "border-border hover:border-foreground/10"
                    )}
                  >
                    {/* Claim header */}
                    <button
                      onClick={() => setExpandedClaim(expandedClaim === i ? null : i)}
                      className="w-full p-3 text-left"
                    >
                      <div className="flex items-start gap-2">
                        <div className="flex-1 min-w-0 space-y-2">
                          <div className="flex items-center gap-2">
                            <TierBadge tier={claim.source.tier} />
                            <span className="text-sm font-medium">
                              &ldquo;{claim.value}&rdquo;
                            </span>
                            {i === 0 && (
                              <span className="text-[10px] bg-foreground/10 px-1.5 py-0.5 rounded">
                                LEADING
                              </span>
                            )}
                          </div>
                          <WeightBar
                            share={claim.weightShare}
                            tier={claim.source.tier}
                            isLeading={i === 0}
                          />
                          <div className="flex items-center gap-3 text-xs text-muted-foreground">
                            <span>{claim.assertionCount} assertions</span>
                            <span>{claim.supportingAgents.length} agents</span>
                            {claim.supportingAgents.length > 0 && (
                              <span>
                                avg trust:{" "}
                                {(
                                  claim.supportingAgents.reduce((a, b) => a + b.trustScore, 0) /
                                  claim.supportingAgents.length
                                ).toFixed(2)}
                              </span>
                            )}
                          </div>
                        </div>
                        <span className="text-muted-foreground text-xs">
                          {expandedClaim === i ? "▼" : "▶"}
                        </span>
                      </div>
                    </button>

                    {/* Expanded details */}
                    {expandedClaim === i && (
                      <div className="px-3 pb-3 space-y-3 border-t border-border pt-3">
                        {/* Source info */}
                        <div className="space-y-1">
                          <div className="text-xs font-medium text-muted-foreground">
                            Source
                          </div>
                          <div className="text-sm">{claim.source.label}</div>
                          <div className="flex items-center gap-2 text-xs">
                            <span className={statusColors[claim.source.status]}>
                              {statusIcons[claim.source.status]} {claim.source.status}
                            </span>
                            <span className="text-muted-foreground">
                              {claim.source.tierLabel}
                            </span>
                          </div>
                          {claim.source.url && (
                            <a
                              href={claim.source.url}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="text-xs text-blue-600 dark:text-blue-400 hover:underline"
                            >
                              {claim.source.url}
                            </a>
                          )}
                        </div>

                        {/* Supporting agents */}
                        {claim.supportingAgents.length > 0 && (
                          <div className="space-y-2">
                            <div className="text-xs font-medium text-muted-foreground">
                              Supporting Agents
                            </div>
                            {claim.supportingAgents.map((agent, j) => (
                              <div key={j} className="flex items-center gap-2">
                                <code className="text-[10px] font-mono bg-muted px-1 py-0.5 rounded">
                                  {agent.agentId.slice(0, 8)}...
                                </code>
                                <div className="flex-1">
                                  <TrustBar score={agent.trustScore} size="sm" />
                                </div>
                              </div>
                            ))}
                          </div>
                        )}

                        {/* Hashes */}
                        <div className="space-y-1">
                          <HashDisplay hash={claim.representativeHash} label="Assertion" />
                          <HashDisplay hash={claim.source.hash} label="Source" />
                          {claim.source.visualHash && (
                            <HashDisplay hash={claim.source.visualHash} label="Visual" />
                          )}
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}

            {/* ============ PROVENANCE TAB ============ */}
            {activeTab === "provenance" && leadingClaim && (
              <div className="space-y-4">
                {/* Chain visualization */}
                <div className="space-y-3">
                  <div className="text-xs font-medium text-muted-foreground">
                    Provenance Chain (Leading Claim)
                  </div>

                  {/* Query */}
                  <div className="flex items-start gap-3">
                    <div className="w-6 h-6 rounded-full bg-foreground/10 flex items-center justify-center text-xs">
                      Q
                    </div>
                    <div className="flex-1 border-l-2 border-dashed border-muted-foreground/30 pl-4 pb-4">
                      <div className="text-xs text-muted-foreground">Query</div>
                      <div className="text-sm font-mono">subject + predicate</div>
                    </div>
                  </div>

                  {/* Lens */}
                  <div className="flex items-start gap-3">
                    <div className="w-6 h-6 rounded-full bg-amber-500/20 flex items-center justify-center text-xs">
                      L
                    </div>
                    <div className="flex-1 border-l-2 border-dashed border-muted-foreground/30 pl-4 pb-4">
                      <div className="text-xs text-muted-foreground">Lens Applied</div>
                      <div className="text-sm font-mono">SkepticLens</div>
                      <div className="text-xs text-muted-foreground mt-1">
                        Computed conflict score via Shannon entropy
                      </div>
                    </div>
                  </div>

                  {/* Assertion */}
                  <div className="flex items-start gap-3">
                    <div className="w-6 h-6 rounded-full bg-blue-500/20 flex items-center justify-center text-xs">
                      A
                    </div>
                    <div className="flex-1 border-l-2 border-dashed border-muted-foreground/30 pl-4 pb-4">
                      <div className="text-xs text-muted-foreground">
                        Representative Assertion
                      </div>
                      <HashDisplay
                        hash={leadingClaim.representativeHash}
                        label="Hash"
                      />
                      <div className="text-xs text-muted-foreground mt-1">
                        Signed by {leadingClaim.supportingAgents.length} agent(s)
                      </div>
                    </div>
                  </div>

                  {/* Source */}
                  <div className="flex items-start gap-3">
                    <div className="w-6 h-6 rounded-full bg-emerald-500/20 flex items-center justify-center text-xs">
                      S
                    </div>
                    <div className="flex-1 pl-4">
                      <div className="text-xs text-muted-foreground">Source Document</div>
                      <div className="text-sm">{leadingClaim.source.label}</div>
                      <div className="flex items-center gap-2 mt-1">
                        <TierBadge tier={leadingClaim.source.tier} size="xs" />
                        <span className="text-xs text-muted-foreground">
                          {leadingClaim.source.tierLabel}
                        </span>
                      </div>
                      <HashDisplay hash={leadingClaim.source.hash} label="Content hash" />
                      {leadingClaim.source.visualHash && (
                        <div className="mt-1">
                          <HashDisplay
                            hash={leadingClaim.source.visualHash}
                            label="Visual anchor (pHash)"
                          />
                        </div>
                      )}
                    </div>
                  </div>
                </div>

                {/* All signers */}
                {leadingClaim.supportingAgents.length > 0 && (
                  <div className="border-t border-border pt-4 space-y-2">
                    <div className="text-xs font-medium text-muted-foreground">
                      Signatories
                    </div>
                    <div className="grid gap-2">
                      {leadingClaim.supportingAgents.map((agent, i) => (
                        <div
                          key={i}
                          className="flex items-center gap-3 p-2 bg-muted/30 rounded"
                        >
                          <code className="text-xs font-mono">{agent.agentId}</code>
                          <div className="flex-1">
                            <TrustBar score={agent.trustScore} />
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* Timestamps */}
                <div className="border-t border-border pt-4 space-y-1 text-xs">
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">Computed at:</span>
                    <span className="font-mono">
                      {new Date(claimData.computedAt).toISOString()}
                    </span>
                  </div>
                  {leadingClaim.timestamp && (
                    <div className="flex justify-between">
                      <span className="text-muted-foreground">Assertion timestamp:</span>
                      <span className="font-mono">
                        {new Date(leadingClaim.timestamp).toISOString()}
                      </span>
                    </div>
                  )}
                </div>
              </div>
            )}

            {/* ============ RAW TAB ============ */}
            {activeTab === "raw" && (
              <div className="space-y-2">
                <div className="text-xs font-medium text-muted-foreground">
                  Raw SkepticResponse (JSON)
                </div>
                <pre className="text-[10px] font-mono bg-muted p-3 rounded overflow-x-auto max-h-[300px]">
                  {JSON.stringify(claimData, null, 2)}
                </pre>
                <button
                  onClick={() => {
                    navigator.clipboard.writeText(JSON.stringify(claimData, null, 2));
                  }}
                  className="text-xs text-muted-foreground hover:text-foreground"
                >
                  Copy to clipboard
                </button>
              </div>
            )}
          </div>
        </div>
        </>,
        document.body
      )}
    </span>
  );
}
