"use client"; import React, { useEffect, useRef, useState } from "react"; import { loadInvestigation, saveInvestigation } from "@/lib/storage/investigation-storage"; import Link from "next/link"; export default function ReportPage({ params }) { const routeId = (typeof params === "object" && params?.id != null) ? String(params.id) : ""; const [existing, setExisting] = useState(null); const [hydrated, setHydrated] = useState(false); const [generationLoading, setGenerationLoading] = useState(false); const [generationError, setGenerationError] = useState(false); const [updateLoading, setUpdateLoading] = useState(false); const generationAttempted = useRef(false); useEffect(() => { setExisting(loadInvestigation(routeId)); setHydrated(true); }, []); // First-generation: create report when none persists (v0.58) useEffect(() => { if (!hydrated) return; if (existing?.investigationReport) return; if (generationAttempted.current) return; generationAttempted.current = true; const situationGraph = existing?.situationGraph; const findings = existing?.findings ?? []; if (!situationGraph) { setGenerationError(true); return; } (async () => { setGenerationLoading(true); try { const res = await fetch("/api/cases/overview", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ situationGraph, findings }), }); if (!res.ok) { setGenerationError(true); return; } const data = await res.json(); if (data.success) { /* ── v0.59a — provenance: record generation revision (does NOT change Investigation revision) ── */ const rev = existing?.investigationRevision ?? 0; const reportData = { understanding: data.understanding, plausibleInterpretations: data.plausibleInterpretations, hasPlausibleInterpretations: true, generatedFromRevision: rev }; setExisting((p) => { saveInvestigation({ ...p, investigationReport: reportData }); return { ...p, investigationReport: reportData }; }); } else { setGenerationError(true); } } catch { setGenerationError(true); } finally { setGenerationLoading(false); } })(); }, [hydrated, existing]); // Manual Report update (v0.59b — freshness manual update) const handleUpdateReport = async () => { if (updateLoading) return; setUpdateLoading(true); const snap = loadInvestigation(routeId); const situationGraph = snap?.situationGraph; const findings = snap?.findings ?? []; const rev = snap?.investigationRevision ?? 0; if (!situationGraph) { setUpdateLoading(false); return; } try { const res = await fetch("/api/cases/overview", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ situationGraph, findings }), }); if (!res.ok) { setUpdateLoading(false); return; } const data = await res.json(); if (data.success) { const reportData = { understanding: data.understanding, plausibleInterpretations: data.plausibleInterpretations, hasPlausibleInterpretations: true, generatedFromRevision: rev }; setExisting((p) => { saveInvestigation({ ...p, investigationReport: reportData }); return { ...p, investigationReport: reportData }; }); } } catch { /* failure: retain existing Report and updateAvailable state */ } finally { setUpdateLoading(false); } }; const report = existing?.investigationReport || null; const scenario = hydrated ? (existing?.scenario || "") : null; const paragraphs = (report?.understanding || "") .split("\n") .filter(Boolean); return (

Investigation Report

{/* Report freshness — only when a Report exists */} {report ? (
{existing?.investigationRevision === report.generatedFromRevision ? ( Current ) : (
Update available The investigation has changed since this report was generated.
)}
) : null} {/* Situation */} {scenario && (

Situation

{scenario}

)} {/* What we understand */} {report ? ( <> {paragraphs.length > 0 ? ( paragraphs.map((p, i) => (

What we understand

{p}

)) ) : (

What we understand

{report.understanding || ""}

)} {/* What remains plausible — conditional */} {report.hasPlausibleInterpretations && report.plausibleInterpretations ? (

What remains plausible

{report.plausibleInterpretations}

) : null} ) : ( /* Skeleton / loading state when no persisted report exists */ <>

What we understand

{generationLoading ? (
Generating report… {[0, 1, 2].map((i) => (
))}
) : generationError ? (

Report generation failed. You may try again from the Investigation page.

) : null}
)} {/* Back to investigation */}
Back to investigation
{/* Back to portfolio */}
Back to portfolio
); }