"use strict";
// Goal alignment tree — Company Mission → Goals → Tasks.
//
// Goals provide traceability from every task back to the company mission.
// Goals can be decomposed into child tasks with dependency chains.
// Progress is rolled up from task completion percentages.
//
// Storage: `.harness/companies/<companyId>/goals.json`
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.listGoals = listGoals;
exports.getGoal = getGoal;
exports.createGoal = createGoal;
exports.updateGoal = updateGoal;
exports.deleteGoal = deleteGoal;
exports.decomposeGoal = decomposeGoal;
exports.getGoalProgress = getGoalProgress;
exports.listGoalProgress = listGoalProgress;
const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const eventStore_1 = require("../persistence/eventStore");
const taskStore_1 = require("./taskStore");
// ─── Persistence ────────────────────────────────────────────────────
function goalsFile(projectDir, companyId) {
    return path.join(projectDir, '.harness', 'companies', companyId, 'goals.json');
}
async function readGoals(projectDir, companyId) {
    try {
        const raw = await fs.readFile(goalsFile(projectDir, companyId), 'utf-8');
        const parsed = JSON.parse(raw);
        return Array.isArray(parsed.goals) ? parsed.goals : [];
    }
    catch {
        return [];
    }
}
async function writeGoals(projectDir, companyId, goals) {
    const fp = goalsFile(projectDir, companyId);
    await fs.mkdir(path.dirname(fp), { recursive: true });
    await fs.writeFile(fp, JSON.stringify({ goals }, null, 2), 'utf-8');
}
// ─── CRUD ───────────────────────────────────────────────────────────
async function listGoals(projectDir, companyId, filter) {
    const goals = await readGoals(projectDir, companyId);
    return goals.filter((g) => {
        if (filter?.status && g.status !== filter.status)
            return false;
        if (filter?.priority && g.priority !== filter.priority)
            return false;
        return true;
    });
}
async function getGoal(projectDir, companyId, id) {
    const goals = await readGoals(projectDir, companyId);
    return goals.find((g) => g.id === id);
}
async function createGoal(projectDir, companyId, input, now = new Date()) {
    if (!input.title?.trim())
        throw new Error('Goal title is required.');
    const goal = {
        id: crypto.randomUUID(),
        companyId,
        title: input.title.trim(),
        description: input.description?.trim() ?? '',
        missionAlignment: input.missionAlignment?.trim() ?? '',
        status: 'active',
        priority: input.priority ?? 'normal',
        targetDate: input.targetDate,
        createdAt: now.toISOString(),
        updatedAt: now.toISOString(),
    };
    const goals = await readGoals(projectDir, companyId);
    goals.push(goal);
    await writeGoals(projectDir, companyId, goals);
    await (0, eventStore_1.emitEvent)(projectDir, 'service', 'goal.created', { goal }, 'system', goal.id).catch(() => { });
    return goal;
}
async function updateGoal(projectDir, companyId, id, input, now = new Date()) {
    const goals = await readGoals(projectDir, companyId);
    const idx = goals.findIndex((g) => g.id === id);
    if (idx === -1)
        throw new Error(`Goal not found: ${id}`);
    const previous = goals[idx];
    const updated = {
        ...previous,
        ...(input.title !== undefined ? { title: input.title.trim() } : {}),
        ...(input.description !== undefined ? { description: input.description.trim() } : {}),
        ...(input.missionAlignment !== undefined ? { missionAlignment: input.missionAlignment.trim() } : {}),
        ...(input.status !== undefined ? { status: input.status } : {}),
        ...(input.priority !== undefined ? { priority: input.priority } : {}),
        ...(input.targetDate !== undefined ? { targetDate: input.targetDate || undefined } : {}),
        updatedAt: now.toISOString(),
    };
    goals[idx] = updated;
    await writeGoals(projectDir, companyId, goals);
    await (0, eventStore_1.emitEvent)(projectDir, 'service', 'goal.updated', { goal: updated, previous }, 'system', updated.id).catch(() => { });
    return updated;
}
async function deleteGoal(projectDir, companyId, id) {
    const goals = await readGoals(projectDir, companyId);
    const idx = goals.findIndex((g) => g.id === id);
    if (idx === -1)
        return false;
    const [removed] = goals.splice(idx, 1);
    await writeGoals(projectDir, companyId, goals);
    await (0, eventStore_1.emitEvent)(projectDir, 'service', 'goal.deleted', { goal: removed }, 'system', id).catch(() => { });
    return true;
}
// ─── Goal decomposition ──────────────────────────────────────────────
/**
 * Decompose a goal into child tasks. Creates one task per prompt with the
 * goal's companyId and goalId set, and optional dependsOn chains.
 */
async function decomposeGoal(projectDir, companyId, goalId, prompts, now = new Date()) {
    const goal = await getGoal(projectDir, companyId, goalId);
    if (!goal)
        throw new Error(`Goal not found: ${goalId}`);
    const tasks = [];
    for (const prompt of prompts) {
        const task = await (0, taskStore_1.createTask)(projectDir, {
            title: prompt.title,
            description: prompt.description,
            priority: prompt.priority ?? goal.priority === 'critical' ? 'high' : goal.priority === 'high' ? 'high' : 'normal',
            companyId,
            goalId,
            dependsOn: prompt.dependsOn,
        }, now);
        tasks.push(task);
    }
    return tasks;
}
// ─── Progress roll-up ────────────────────────────────────────────────
/**
 * Calculate progress for a goal by aggregating its child tasks.
 * Returns completion stats and an overall progress percentage.
 */
async function getGoalProgress(projectDir, companyId, goalId) {
    const goal = await getGoal(projectDir, companyId, goalId);
    if (!goal)
        throw new Error(`Goal not found: ${goalId}`);
    const tasks = await (0, taskStore_1.listTasks)(projectDir, { companyId, goalId });
    const totalTasks = tasks.length;
    const completedTasks = tasks.filter((t) => t.status === 'done').length;
    const progressPercent = totalTasks > 0
        ? Math.round(tasks.reduce((sum, t) => sum + t.progressPercent, 0) / totalTasks)
        : 0;
    return {
        goalId,
        companyId,
        totalTasks,
        completedTasks,
        progressPercent,
        status: goal.status,
    };
}
/**
 * Roll up progress for all goals in a company.
 */
async function listGoalProgress(projectDir, companyId) {
    const goals = await listGoals(projectDir, companyId);
    const results = [];
    for (const goal of goals) {
        results.push(await getGoalProgress(projectDir, companyId, goal.id));
    }
    return results;
}
//# sourceMappingURL=goals.js.map