import { i as listCustomerSlugs } from "./customer-dir-CkMMXhb0.js";
import { i as writeJsonFile, n as readJsonFile } from "./json-store-WWsFzXub.js";
import { n as readPipelineSync } from "./pipeline-writer-CIllfnZl.js";
import { t as scoreOpportunity } from "./opportunity-score-BTMOQSTV.js";
import path from "path";
//#region src/core/lead-model.ts
const MODEL_FILE = ".agentic/lead-model.json";
const FEATURES = 2;
function modelPath(dataDir) {
	return path.join(dataDir, MODEL_FILE);
}
function features(deal) {
	return [Math.log10((deal.value ?? 0) + 1), (deal.probability ?? 0) / 100];
}
function sigmoid(z) {
	return 1 / (1 + Math.exp(-z));
}
/** Read every customer's closed (won/lost) deals as labelled training rows. */
function gatherTrainingDeals(dataDir) {
	const rows = [];
	for (const slug of listCustomerSlugs(dataDir)) {
		let deals = [];
		try {
			deals = readPipelineSync(dataDir, slug);
		} catch {
			deals = [];
		}
		for (const d of deals) if (d.stage === "won") rows.push({
			x: features(d),
			y: 1
		});
		else if (d.stage === "lost") rows.push({
			x: features(d),
			y: 0
		});
	}
	return rows;
}
/** Train a logistic-regression model from the workspace's won/lost history. */
function buildLeadModel(dataDir) {
	const rows = gatherTrainingDeals(dataDir);
	const classes = new Set(rows.map((r) => r.y));
	const sufficient = rows.length >= 4 && classes.size === 2;
	const empty = {
		weights: new Array(FEATURES).fill(0),
		bias: 0,
		mean: new Array(FEATURES).fill(0),
		std: new Array(FEATURES).fill(1),
		trainedOn: rows.length,
		sufficient
	};
	if (!sufficient) return empty;
	const mean = new Array(FEATURES).fill(0);
	for (const r of rows) for (let j = 0; j < FEATURES; j++) mean[j] += r.x[j] / rows.length;
	const std = new Array(FEATURES).fill(0);
	for (const r of rows) for (let j = 0; j < FEATURES; j++) std[j] += (r.x[j] - mean[j]) ** 2 / rows.length;
	for (let j = 0; j < FEATURES; j++) std[j] = Math.sqrt(std[j]) || 1;
	const norm = rows.map((r) => ({
		x: r.x.map((v, j) => (v - mean[j]) / std[j]),
		y: r.y
	}));
	const weights = new Array(FEATURES).fill(0);
	let bias = 0;
	const lr = .1;
	const iterations = 2e3;
	for (let it = 0; it < iterations; it++) {
		const gradW = new Array(FEATURES).fill(0);
		let gradB = 0;
		for (const r of norm) {
			const err = sigmoid(bias + weights.reduce((acc, w, j) => acc + w * r.x[j], 0)) - r.y;
			for (let j = 0; j < FEATURES; j++) gradW[j] += err * r.x[j] / norm.length;
			gradB += err / norm.length;
		}
		for (let j = 0; j < FEATURES; j++) weights[j] -= lr * gradW[j];
		bias -= lr * gradB;
	}
	return {
		weights,
		bias,
		mean,
		std,
		trainedOn: rows.length,
		sufficient: true
	};
}
/** Predict win probability (0–1). Falls back to the heuristic when untrained. */
function predictWin(model, deal) {
	if (!model.sufficient) return scoreOpportunity(deal).score / 100;
	const x = features(deal).map((v, j) => (v - model.mean[j]) / model.std[j]);
	return sigmoid(model.bias + model.weights.reduce((acc, w, j) => acc + w * x[j], 0));
}
function saveLeadModel(dataDir, model) {
	writeJsonFile(modelPath(dataDir), model);
}
function loadLeadModel(dataDir) {
	return readJsonFile(modelPath(dataDir), null);
}
//#endregion
export { buildLeadModel, loadLeadModel, predictWin, saveLeadModel };

//# sourceMappingURL=lead-model-CEmx7te7.js.map