/**
 * low-confidence-attribution card — LLM-driven uncertain-attribution finder.
 *
 * Model: claude-sonnet-4-6 (routine per AI-SPEC §4 model routing)
 * Version: low-confidence-attribution@0.1.0
 *
 * Landmine 11: this card reads `ctx.judgmentAttributions` (NOT Report.summary).
 * Returns `status: "missing"` when attributions are undefined or empty BEFORE
 * calling the LLM — this is a structural seam, not an error path.
 *
 * Schema is in the D0045 trust-boundary scan root; `satisfies` clause is
 * mandatory.
 *
 * @see .planning/phases/05-diagnosis-engine-cli-llm-cards/05-RESEARCH.md (Landmine 11)
 * @see docs/decisions/D0052-judgment-ref-granularity.md
 */
import { z } from "zod";
import { modelId as mkModelId } from "../../../ports/llm-client.js";
import { buildLowConfidenceAttributionPrompt } from "../prompt-builders.js";
// ---------------------------------------------------------------------------
// Body schema (D0045 trust boundary — satisfies required)
// ---------------------------------------------------------------------------
export const LowConfidenceAttributionBodySchema = z.object({
    summary: z.string().min(1).max(800),
    judgmentRefs: z
        .array(z.object({
        taskId: z.string().min(1),
        modelId: z.string().min(1),
        dimension: z.string().min(1),
    }))
        .min(1),
});
// ---------------------------------------------------------------------------
// Generator
// ---------------------------------------------------------------------------
const CARD_MODEL = mkModelId("anthropic:claude-sonnet-4-6");
export const generateLowConfidenceAttribution = async (report, ctx) => {
    // C1: no LLM → missing
    if (!ctx.llm) {
        return {
            status: "missing",
            cardType: "low-confidence-attribution",
            reason: "no LLMClient wired",
        };
    }
    // L1: Landmine 11 — short-circuit BEFORE calling LLM when no attribution data
    if (!ctx.judgmentAttributions || ctx.judgmentAttributions.length === 0) {
        return {
            status: "missing",
            cardType: "low-confidence-attribution",
            reason: "no attribution data for this run",
        };
    }
    // Also short-circuit when every JudgmentAttribution has an empty
    // `attributions` array. The card schema requires `judgmentRefs.min(1)`, so
    // the LLM would have nothing to cite — degrade gracefully instead of
    // building an empty-table prompt and failing parse downstream.
    const hasAnyAttributions = ctx.judgmentAttributions.some((ja) => ja.attributions.length > 0);
    if (!hasAnyAttributions) {
        return {
            status: "missing",
            cardType: "low-confidence-attribution",
            reason: "attribution entries exist but all are empty",
        };
    }
    const prompt = buildLowConfidenceAttributionPrompt(report, ctx.judgmentAttributions);
    // Destructure `cost` and `model` from the LLMClient return —
    // already provided per llm-client.ts:139-144, previously discarded.
    const { value, usage, cost, model } = await ctx.llm.completeStructured({
        model: CARD_MODEL,
        prompt: `${prompt.system}\n\n${prompt.user}`,
        schema: LowConfidenceAttributionBodySchema,
        temperature: 0.1,
        maxTokens: 2000,
        context: {
            feature: "diagnosis",
            runId: ctx.runId,
            cardId: "low-confidence-attribution",
        },
    });
    return {
        status: "ready",
        cardType: "low-confidence-attribution",
        body: value,
        meta: {
            cardVersion: "low-confidence-attribution@0.1.0",
            tokenUsage: { input: usage.promptTokens, output: usage.completionTokens },
            generatedAt: new Date().toISOString(),
            cost,
            model,
        },
    };
};
