/**
 * Knowledge compounding — distills high-confidence judgment-log entries from a
 * milestone window into .sf/KNOWLEDGE.md after milestone close.
 *
 * Called by postUnitPostVerification after complete-milestone, alongside
 * scaffold-keeper and record-promoter. Failure is always non-fatal.
 *
 * Strategy (stub implementation):
 *   - Read judgment-log.jsonl entries with confidence=high for the given milestone
 *   - For each, generate: `- [M00X] {decision}: {reasoning}`
 *   - Append under `## Learned during M00X` section in .sf/KNOWLEDGE.md
 *   - Deduplicate against existing entries (exact decision+reasoning match)
 */

import {
	existsSync,
	mkdirSync,
	readFileSync,
	writeFileSync,
} from "node:fs";
import { dirname, join } from "node:path";

import { readJudgmentLog } from "./judgment-log.js";
import { sfRoot } from "./paths.js";

export interface CompoundLearningsResult {
	added: number;
	skipped: number;
}

/**
 * Compound high-confidence judgment-log entries into KNOWLEDGE.md.
 *
 * @param basePath - project root (cwd)
 * @param milestoneId - milestone just completed (e.g. "M001")
 */
export function compoundLearningsIntoKnowledge(
	basePath: string,
	milestoneId: string,
): CompoundLearningsResult {
	const sfDir = sfRoot(basePath);
	const knowledgePath = join(sfDir, "KNOWLEDGE.md");
	const sectionHeading = `## Learned during ${milestoneId}`;

	// Read high-confidence entries for this milestone
	const entries = readJudgmentLog(basePath, milestoneId).filter(
		(e) => e.confidence === "high",
	);

	if (entries.length === 0) return { added: 0, skipped: 0 };

	// Load or initialise KNOWLEDGE.md
	let existing = "";
	if (existsSync(knowledgePath)) {
		try {
			existing = readFileSync(knowledgePath, "utf-8");
		} catch {
			return { added: 0, skipped: 0 };
		}
	}

	// Deduplicate: collect existing learned lines under our section (or globally)
	const existingLines = new Set(
		existing
			.split("\n")
			.map((l) => l.trim())
			.filter((l) => l.startsWith("- [")),
	);

	let added = 0;
	let skipped = 0;
	const newLines: string[] = [];

	for (const entry of entries) {
		const line = `- [${milestoneId}] ${entry.decision}: ${entry.reasoning}`;
		if (existingLines.has(line)) {
			skipped++;
		} else {
			newLines.push(line);
			added++;
		}
	}

	if (added === 0) return { added: 0, skipped };

	// Append or create section
	let updated: string;
	if (existing.includes(sectionHeading)) {
		// Section already exists — append after the heading line
		const idx = existing.indexOf(sectionHeading);
		const afterHeading = existing.indexOf("\n", idx + sectionHeading.length);
		const insertPos = afterHeading !== -1 ? afterHeading + 1 : existing.length;
		updated =
			existing.slice(0, insertPos) +
			newLines.join("\n") +
			"\n" +
			existing.slice(insertPos);
	} else if (!existing.trim()) {
		// New file
		updated = `# Project Knowledge\n\n${sectionHeading}\n\n${newLines.join("\n")}\n`;
	} else {
		// Append new section at end
		updated =
			existing.trimEnd() + `\n\n${sectionHeading}\n\n${newLines.join("\n")}\n`;
	}

	try {
		mkdirSync(dirname(knowledgePath), { recursive: true });
		writeFileSync(knowledgePath, updated, "utf-8");
	} catch {
		return { added: 0, skipped };
	}

	return { added, skipped };
}
