/**
 * src/autonomy/agenda.ts
 *
 * Persistent goals/KPIs Muassis is driving toward across sessions.
 * This is what graduates the agent from "answers questions" to "owns outcomes."
 */
import { randomUUID } from 'node:crypto';
import { supabase } from '../utils/supabase.js';
import { createChildLogger } from '../utils/logger.js';
import * as journal from './journal.js';
const log = createChildLogger('autonomy:agenda');
export async function createGoal(tenantId, input) {
    const id = randomUUID();
    const now = new Date().toISOString();
    const row = {
        id,
        tenant_id: tenantId,
        title: input.title,
        description: input.description ?? null,
        category: input.category ?? 'general',
        target_value: input.target_value ?? null,
        current_value: 0,
        unit: input.unit ?? null,
        deadline: input.deadline ?? null,
        status: 'active',
        priority: input.priority ?? 3,
        metadata: {},
        created_at: now,
        updated_at: now,
    };
    const { error } = await supabase.from('agenda_goals').insert(row);
    if (error) {
        throw new Error(`createGoal failed: ${error.message}`);
    }
    log.info({ tenantId, id, title: input.title }, 'goal created');
    // (v3.0.5) Record a journal entry so the KG mirror picks this goal up
    // and surfaces it in the Memory tab's force-directed graph. Without
    // this, goals lived in agenda_goals only and never appeared on the
    // "everything in the KG" graph the user explicitly asked for.
    // Fire-and-forget — a journal write failure should never block goal
    // creation itself.
    void journal.record({
        tenantId,
        kind: 'goal_created',
        actor: 'owner',
        action: input.title,
        target: id,
        outcome: 'success',
        metadata: {
            description: input.description ?? null,
            category: input.category ?? 'general',
            priority: input.priority ?? 3,
            target_value: input.target_value ?? null,
            unit: input.unit ?? null,
            deadline: input.deadline ?? null,
        },
        relatedGoalId: id,
    }).catch((err) => log.warn({ tenantId, id, err: err.message }, 'journal.record(goal_created) failed (non-fatal)'));
    return row;
}
export async function listActiveGoals(tenantId) {
    const { data, error } = await supabase
        .from('agenda_goals')
        .select('*')
        .eq('tenant_id', tenantId)
        .eq('status', 'active')
        .order('priority', { ascending: true });
    if (error) {
        log.warn({ error: error.message }, 'listActiveGoals failed');
        return [];
    }
    return (data ?? []);
}
export async function getGoal(tenantId, id) {
    const { data, error } = await supabase
        .from('agenda_goals')
        .select('*')
        .eq('tenant_id', tenantId)
        .eq('id', id)
        .maybeSingle();
    if (error) {
        log.warn({ error: error.message }, 'getGoal failed');
        return null;
    }
    return data ?? null;
}
export async function incrementGoalProgress(tenantId, goalId, delta) {
    const goal = await getGoal(tenantId, goalId);
    if (!goal)
        return null;
    const next = (goal.current_value ?? 0) + delta;
    const reached = goal.target_value != null && next >= goal.target_value;
    const updated = {
        current_value: next,
        status: (reached ? 'achieved' : goal.status),
        updated_at: new Date().toISOString(),
    };
    const { error } = await supabase
        .from('agenda_goals')
        .update(updated)
        .eq('tenant_id', tenantId)
        .eq('id', goalId);
    if (error) {
        log.warn({ error: error.message }, 'incrementGoalProgress failed');
        return null;
    }
    return { ...goal, ...updated };
}
export async function archiveGoal(tenantId, goalId) {
    await supabase
        .from('agenda_goals')
        .update({ status: 'archived', updated_at: new Date().toISOString() })
        .eq('tenant_id', tenantId)
        .eq('id', goalId);
}
export async function summarizeAgenda(tenantId) {
    const goals = await listActiveGoals(tenantId);
    const { data: achieved } = await supabase
        .from('agenda_goals')
        .select('id', { count: 'exact', head: true })
        .eq('tenant_id', tenantId)
        .eq('status', 'achieved');
    const { data: missed } = await supabase
        .from('agenda_goals')
        .select('id', { count: 'exact', head: true })
        .eq('tenant_id', tenantId)
        .eq('status', 'missed');
    const now = Date.now();
    const sevenDaysMs = 7 * 24 * 3600 * 1000;
    const upcomingDeadlines = goals
        .filter(g => g.deadline && new Date(g.deadline).getTime() - now <= sevenDaysMs)
        .sort((a, b) => new Date(a.deadline ?? 0).getTime() - new Date(b.deadline ?? 0).getTime());
    return {
        active: goals.length,
        achieved: achieved?.count ?? 0,
        missed: missed?.count ?? 0,
        highPriority: goals.filter(g => g.priority <= 2).slice(0, 5),
        upcomingDeadlines: upcomingDeadlines.slice(0, 5),
    };
}
//# sourceMappingURL=agenda.js.map