import type { FactBand, FactStatus } from '@pig/core'; import { Clock3, ExternalLink, Link2, ScanSearch } from 'lucide-react'; import type { ReactNode } from 'react'; import { Badge } from '@/components/ui'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { Separator } from '@/components/ui/separator'; import { cn } from '@/lib/utils'; export interface SourcedFact { id: string; field: string; value: string; score: string | number; band: FactBand; status: FactStatus; evidence: Record | null; sourceUrl: string | null; method: string | null; observedAt: string; } interface SourcedValueProps { value: ReactNode; fact: SourcedFact; className?: string; } const BAND_TONE = { verified: 'positive', probable: 'info', possible: 'warning', } as const; function safeSourceUrl(value: string | null): string | null { if (!value) return null; try { const url = new URL(value); return url.protocol === 'https:' || url.protocol === 'http:' ? url.href : null; } catch { return null; } } function evidenceSummary(evidence: Record | null): string | null { if (!evidence) return null; for (const key of ['excerpt', 'quote', 'summary', 'snippet', 'reason']) { const value = evidence[key]; if (typeof value === 'string' && value.trim()) return value.trim(); } const firstText = Object.values(evidence).find( (value): value is string => typeof value === 'string' && Boolean(value.trim()), ); return firstText?.trim() ?? null; } function humanise(value: string): string { return value.replaceAll('_', ' ').replace(/\b\w/g, (letter) => letter.toUpperCase()); } export function SourcedValue({ value, fact, className }: SourcedValueProps) { const sourceUrl = safeSourceUrl(fact.sourceUrl); const summary = evidenceSummary(fact.evidence); const score = Number(fact.score); const confidence = Number.isFinite(score) ? `${Math.round(score * 100)}%` : 'Not scored'; const observedDate = new Date(fact.observedAt); const observedLabel = Number.isNaN(observedDate.getTime()) ? 'Observation date unavailable' : observedDate.toLocaleDateString(undefined, { dateStyle: 'medium' }); const sourceHost = sourceUrl ? new URL(sourceUrl).hostname.replace(/^www\./, '') : null; return ( {value}

Source evidence · {humanise(fact.field)}

{fact.value}

{confidence}

Evidence

{summary ?? 'No evidence excerpt was recorded.'}

{humanise(fact.band)} {humanise(fact.status)} {fact.method ? via {humanise(fact.method)} : null}
Observed
{sourceUrl ? ( Open source{sourceHost ? ` · ${sourceHost}` : ''} ) : null}
); }