import { int } from "neo4j-driver";
import { getSession } from "../lib/neo4j.js";
function computeHealthSignal(health) {
    const { totalTasks, overdueTasks, blockedTasks, daysSinceLastProgress } = health;
    // No due dates set — report completion count only
    if (totalTasks === 0)
        return "grey";
    // Red: multiple overdue OR critical-path blocker OR no progress for 7+ days
    if (overdueTasks > 1 || (daysSinceLastProgress !== null && daysSinceLastProgress >= 7)) {
        return "red";
    }
    // Amber: at least one overdue OR at least one blocker
    if (overdueTasks > 0 || blockedTasks > 0) {
        return "amber";
    }
    return "green";
}
export async function projectList(params) {
    const { accountId, status, limit = 20 } = params;
    // Default: return pending + active projects
    const statuses = status ? [status] : ["pending", "active"];
    const session = getSession();
    try {
        const result = await session.run(`MATCH (p:Project {accountId: $accountId})
       WHERE p.status IN $statuses
       OPTIONAL MATCH (p)-[:HAS_TASK]->(child:Task)
       WITH p,
         count(child) AS totalTasks,
         count(CASE WHEN child.status = 'completed' THEN 1 END) AS completedTasks,
         count(CASE WHEN child.dueDate IS NOT NULL
           AND date(child.dueDate) < date()
           AND child.status <> 'completed' THEN 1 END) AS overdueTasks,
         count(CASE WHEN EXISTS {
           MATCH (blocker:Task)-[:BLOCKS]->(child)
           WHERE blocker.status IN ['pending', 'active']
         } THEN 1 END) AS blockedTasks,
         max(CASE WHEN child.status = 'completed' THEN child.updatedAt END) AS lastCompletedAt
       RETURN p, totalTasks, completedTasks, overdueTasks, blockedTasks, lastCompletedAt
       ORDER BY p.updatedAt DESC
       LIMIT $limit`, { accountId, statuses, limit: int(limit) });
        const projects = result.records.map((rec) => {
            const p = rec.get("p").properties;
            const totalTasks = rec.get("totalTasks").toNumber?.() ?? Number(rec.get("totalTasks"));
            const completedTasks = rec.get("completedTasks").toNumber?.() ?? Number(rec.get("completedTasks"));
            const overdueTasks = rec.get("overdueTasks").toNumber?.() ?? Number(rec.get("overdueTasks"));
            const blockedTasks = rec.get("blockedTasks").toNumber?.() ?? Number(rec.get("blockedTasks"));
            const lastCompletedAt = rec.get("lastCompletedAt");
            let daysSinceLastProgress = null;
            if (lastCompletedAt) {
                const ms = Date.now() - new Date(lastCompletedAt).getTime();
                daysSinceLastProgress = Math.floor(ms / (1000 * 60 * 60 * 24));
            }
            const healthData = { totalTasks, completedTasks, overdueTasks, blockedTasks, daysSinceLastProgress };
            const signal = computeHealthSignal(healthData);
            const summary = {
                projectId: p.taskId,
                name: p.name,
                tier: p.tier,
                phase: p.phase,
                status: p.status,
                health: { signal, ...healthData },
                updatedAt: p.updatedAt,
            };
            if (p.clientRef)
                summary.clientRef = p.clientRef;
            if (p.targetDate)
                summary.targetDate = p.targetDate;
            return summary;
        });
        console.error(`project-list: returned ${projects.length} projects`);
        return projects;
    }
    catch (err) {
        console.error(`project-list: failed — ${err instanceof Error ? err.message : String(err)}`);
        throw err;
    }
    finally {
        await session.close();
    }
}
//# sourceMappingURL=project-list.js.map