/**
 * weakest-area card — LLM-driven weakest area identification.
 *
 * Model: claude-sonnet-4-6 (routine per AI-SPEC §4 model routing)
 * Version: weakest-area@0.1.0
 *
 * Mitigations:
 * - failure-mode #3: sampleSize = report.areas[area].judgmentCount (per-call refine W2)
 * - failure-mode #3: sampleSize < 10 → confidence.level must be "low" (per-call refine W3)
 * - failure-mode #4: taxonomy drift → buildFailureModeRefinement() Zod predicate
 *
 * Per-call schemas live INSIDE the generator (AI-SPEC §3 Pitfall 1 — no
 * module-scope mutables that change across calls).
 *
 * Schema is in the D0045 trust-boundary scan root; `satisfies` clause is
 * mandatory (cards/ is a SCAN_ROOT in check-trust-boundary-satisfies.ts).
 *
 * @see .planning/phases/05-diagnosis-engine-cli-llm-cards/05-AI-SPEC.md §3
 */
import { z } from "zod";
import { ConfidenceSchema } from "../../../schemas/confidence-schema.js";
import { modelId as mkModelId } from "../../../ports/llm-client.js";
import { buildFailureModeRefinement } from "../card-validators.js";
import { buildWeakestAreaPrompt } from "../prompt-builders.js";
// ---------------------------------------------------------------------------
// Module-level schema: static shape + D-05 taxonomy refine
// ---------------------------------------------------------------------------
/**
 * Module-level schema asserts the static shape + taxonomy constraint (D-05).
 * Per-call schemas add the sampleSize (W2) and small-sample confidence (W3)
 * refinements inside the generator, since they need runtime `report` data.
 */
export const WeakestAreaBodySchema = z
    .object({
    summary: z.string().min(1).max(800),
    area: z.string().min(1),
    dimension: z.string().min(1),
    failureMode: z.string().min(1),
    sampleSize: z.number().int().nonnegative(),
    confidence: ConfidenceSchema,
})
    .refine(buildFailureModeRefinement(), {
    message: "failureMode is not in the canonical taxonomy for this dimension",
    path: ["failureMode"],
});
// ---------------------------------------------------------------------------
// Generator
// ---------------------------------------------------------------------------
const CARD_MODEL = mkModelId("anthropic:claude-sonnet-4-6");
export const generateWeakestArea = async (report, ctx) => {
    // C1: no LLM → missing
    if (!ctx.llm) {
        return {
            status: "missing",
            cardType: "weakest-area",
            reason: "no LLMClient wired",
        };
    }
    const scores = report.summary.scores ?? [];
    if (scores.length === 0) {
        return {
            status: "missing",
            cardType: "weakest-area",
            reason: "report has no areas",
        };
    }
    // Per-call schema: close over report to get sampleSize + confidence constraints
    // (AI-SPEC §3 Pitfall 1 — never hoist to module scope)
    const PerCallSchema = z
        .object({
        summary: z.string().min(1).max(800),
        area: z.string().min(1),
        dimension: z.string().min(1),
        failureMode: z.string().min(1),
        sampleSize: z.number().int().nonnegative(),
        confidence: ConfidenceSchema,
    })
        .refine(buildFailureModeRefinement(), {
        message: "failureMode is not in the canonical taxonomy for this dimension",
        path: ["failureMode"],
    })
        // W3: small-sample forces confidence.level = "low"
        .refine((body) => {
        if (body.sampleSize < 10)
            return body.confidence.level === "low";
        return true;
    }, {
        message: 'When sampleSize < 10, confidence.level must be "low"',
        path: ["confidence", "level"],
    });
    const prompt = buildWeakestAreaPrompt(report);
    // 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: PerCallSchema,
        temperature: 0.1,
        maxTokens: 2000,
        context: {
            feature: "diagnosis",
            runId: ctx.runId,
            cardId: "weakest-area",
        },
    });
    return {
        status: "ready",
        cardType: "weakest-area",
        body: value,
        meta: {
            cardVersion: "weakest-area@0.1.0",
            tokenUsage: { input: usage.promptTokens, output: usage.completionTokens },
            generatedAt: new Date().toISOString(),
            cost,
            model,
        },
    };
};
