function nonEmptyStrings(value, field, findings) {
    if (!Array.isArray(value) || value.length === 0) {
        findings.push({ code: "wbs-field-empty", message: `${field} must be a non-empty string array`, field });
        return null;
    }
    const out = value.filter((x) => typeof x === "string" && x.trim().length > 0).map((x) => x.trim());
    if (out.length === 0) {
        findings.push({ code: "wbs-field-empty", message: `${field} must contain at least one non-empty string`, field });
        return null;
    }
    return out;
}
/** Structural guard for WBS rows (schema validation is separate — see plan-artifact JSON Schema). */
export function validatePlanArtifactWbsItemShape(item) {
    const findings = [];
    if (!item || typeof item !== "object" || Array.isArray(item)) {
        return {
            ok: false,
            code: "wbs-shape-invalid",
            findings: [{ code: "wbs-not-object", message: "WBS item must be an object" }]
        };
    }
    const row = item;
    const requireString = (key) => {
        const v = row[key];
        if (typeof v !== "string" || v.trim().length === 0) {
            findings.push({ code: "wbs-field-missing", message: `WBS item requires non-empty '${key}'`, field: key });
            return "";
        }
        return v.trim();
    };
    requireString("wbsId");
    requireString("title");
    requireString("suggestedTaskTitle");
    requireString("approach");
    requireString("doneMeans");
    nonEmptyStrings(row.goalMapping, "goalMapping", findings);
    nonEmptyStrings(row.technicalScope, "technicalScope", findings);
    nonEmptyStrings(row.acceptanceCriteria, "acceptanceCriteria", findings);
    nonEmptyStrings(row.testingVerification, "testingVerification", findings);
    if (!Array.isArray(row.dependsOn)) {
        findings.push({
            code: "wbs-field-missing",
            message: "WBS item requires 'dependsOn' array",
            field: "dependsOn"
        });
    }
    const confidence = row.sizingConfidence;
    if (confidence !== "high" && confidence !== "medium" && confidence !== "low") {
        findings.push({
            code: "wbs-field-invalid",
            message: "WBS item requires sizingConfidence of high, medium, or low",
            field: "sizingConfidence"
        });
    }
    const payload = row.generatedTaskPayload;
    if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
        findings.push({
            code: "wbs-payload-missing",
            message: "WBS item requires generatedTaskPayload object",
            field: "generatedTaskPayload"
        });
    }
    else {
        const p = payload;
        if (typeof p.title !== "string" || !p.title.trim()) {
            findings.push({
                code: "wbs-payload-field-missing",
                message: "generatedTaskPayload requires non-empty title",
                field: "generatedTaskPayload.title"
            });
        }
        if (typeof p.approach !== "string" || !p.approach.trim()) {
            findings.push({
                code: "wbs-payload-field-missing",
                message: "generatedTaskPayload requires approach",
                field: "generatedTaskPayload.approach"
            });
        }
        nonEmptyStrings(p.technicalScope, "generatedTaskPayload.technicalScope", findings);
        nonEmptyStrings(p.acceptanceCriteria, "generatedTaskPayload.acceptanceCriteria", findings);
    }
    if (findings.length > 0) {
        return { ok: false, code: "wbs-shape-invalid", findings };
    }
    return { ok: true, item: item };
}
export function isPlanArtifactWbsItem(value) {
    return validatePlanArtifactWbsItemShape(value).ok === true;
}
function phaseLabelFromKey(phaseKey) {
    return /^\d+$/.test(phaseKey) ? `Phase ${phaseKey}` : phaseKey;
}
/**
 * Stub normalizer (WP-1.3): maps a WBS row to a persist-compatible task draft.
 * Full provenance attachment and id allocation happen in WP-6 finalize.
 */
export function normalizeWbsItemToTaskDraft(item, context) {
    const guarded = validatePlanArtifactWbsItemShape(item);
    if (!guarded.ok) {
        return guarded;
    }
    const wbs = guarded.item;
    const payload = wbs.generatedTaskPayload;
    const phaseKey = (typeof payload.phaseKey === "string" && payload.phaseKey.trim()) ||
        (typeof wbs.recommendedPhase === "string" && wbs.recommendedPhase.trim()) ||
        context.defaultPhaseKey;
    const phase = (typeof payload.phase === "string" && payload.phase.trim()) ||
        (phaseKey ? phaseLabelFromKey(phaseKey) : context.defaultPhase);
    const planningProvenance = {
        planId: context.planId,
        planVersion: context.planVersion,
        wbsId: wbs.wbsId,
        wbsPath: wbs.path,
        planRef: context.planRef,
        planningType: context.planningType,
        source: "normalize-wbs-to-task-draft"
    };
    const draft = {
        id: typeof payload.id === "string" && /^T\d+$/.test(payload.id.trim()) ? payload.id.trim() : undefined,
        title: payload.title.trim(),
        type: payload.type?.trim() || "workspace-kit",
        priority: payload.priority,
        phase,
        phaseKey: phaseKey || undefined,
        approach: payload.approach.trim(),
        technicalScope: [...payload.technicalScope],
        acceptanceCriteria: [...payload.acceptanceCriteria],
        dependsOn: wbs.dependsOn.length > 0 ? [...wbs.dependsOn] : payload.dependsOn ? [...payload.dependsOn] : undefined,
        status: payload.status ?? context.defaultStatus ?? "proposed",
        metadata: {
            planRef: context.planRef,
            planningProvenance
        }
    };
    return {
        ok: true,
        draft,
        planningProvenance
    };
}
