/**
 * PlanService — CRUD for automation plans.
 *
 * A plan holds a list of proposed tasks for a repository.
 * Each task can become a thread when the human approves and starts it.
 */
import { eq, desc } from "drizzle-orm";
import { automationPlans } from "../db/schema.js";
import { uuidv7 } from "../db/uuidv7.js";
// ── Helpers ──────────────────────────────────────────────────────────
function parseTasks(raw) {
    try {
        const parsed = JSON.parse(raw);
        return Array.isArray(parsed) ? parsed : [];
    }
    catch {
        return [];
    }
}
function hydrate(row) {
    return { ...row, tasks: parseTasks(row.tasks) };
}
export function newTaskId() {
    return uuidv7().slice(-8);
}
// ── Service ──────────────────────────────────────────────────────────
export class PlanService {
    db;
    constructor(db) {
        this.db = db;
    }
    create(params) {
        const id = uuidv7();
        const now = new Date().toISOString();
        const tasks = params.tasks ?? [];
        this.db
            .insert(automationPlans)
            .values({
            id,
            repoId: params.repoId,
            userId: params.userId ?? null,
            title: params.title,
            status: "draft",
            tasks: JSON.stringify(tasks),
            createdAt: now,
            updatedAt: now,
        })
            .run();
        return this.getById(id);
    }
    getById(id) {
        const row = this.db
            .select()
            .from(automationPlans)
            .where(eq(automationPlans.id, id))
            .get();
        return row ? hydrate(row) : undefined;
    }
    listByRepo(repoId) {
        return this.db
            .select()
            .from(automationPlans)
            .where(eq(automationPlans.repoId, repoId))
            .orderBy(desc(automationPlans.updatedAt))
            .all()
            .map(hydrate);
    }
    listByUser(userId) {
        return this.db
            .select()
            .from(automationPlans)
            .where(eq(automationPlans.userId, userId))
            .orderBy(desc(automationPlans.updatedAt))
            .all()
            .map(hydrate);
    }
    update(id, params) {
        const now = new Date().toISOString();
        const set = { updatedAt: now };
        if (params.title !== undefined)
            set.title = params.title;
        if (params.status !== undefined)
            set.status = params.status;
        if (params.tasks !== undefined)
            set.tasks = JSON.stringify(params.tasks);
        this.db
            .update(automationPlans)
            .set(set)
            .where(eq(automationPlans.id, id))
            .run();
        return this.getById(id);
    }
    /** Update a single task within a plan */
    updateTask(planId, taskId, patch) {
        const plan = this.getById(planId);
        if (!plan)
            return undefined;
        const tasks = plan.tasks.map((t) => t.id === taskId ? { ...t, ...patch } : t);
        return this.update(planId, { tasks });
    }
    delete(id) {
        this.db
            .delete(automationPlans)
            .where(eq(automationPlans.id, id))
            .run();
    }
}
//# sourceMappingURL=plans.js.map