import z from "zod";
import { addMigrationChecklistItem, isMigrationChecklistActive, readMigrationChecklist, updateMigrationChecklistItem, } from "../../../migration/migration-checklist.js";
import { createToolFactory, ToolCategory } from "../tools2/types.js";
// Store checklist state in Clark context
const getChecklistState = (clark) => {
    if (!clark.context.checklist) {
        clark.context.checklist = {
            items: [],
            lastUpdated: new Date().toISOString(),
        };
    }
    return clark.context.checklist;
};
const getChecklistStateIfPresent = (clark) => {
    if (!clark.context.checklist) {
        return null;
    }
    return clark.context.checklist;
};
const updateChecklistState = (clark, newState) => {
    clark.context.checklist = {
        ...newState,
        lastUpdated: new Date().toISOString(),
    };
};
// Export function to be used by other tools
export const checkChecklistCompletion = (clark) => {
    const checklistState = getChecklistStateIfPresent(clark);
    if (!checklistState) {
        return {
            complete: true,
            pendingTasks: [],
        };
    }
    const pendingTasks = checklistState.items.filter((item) => item.status === "pending" || item.status === "in_progress");
    return {
        complete: pendingTasks.length === 0,
        pendingTasks,
    };
};
export const buildManageChecklistToolFactory = createToolFactory("build_manageChecklist", ({ clark, services, }) => {
    return {
        category: ToolCategory.GENERAL,
        description: `
      Manage a dynamic checklist of tasks to complete during agent execution.
      Use this tool to create, update, and track progress on tasks.

      This tool supports:
      - Adding new checklist items
      - Updating item status (pending, in_progress, completed, cancelled, failed)
      - Updating item content
      - Recording why a task failed (via failureReason, used only with status "failed")
      - Retrieving current checklist state

      Use status "failed" when a task cannot be completed deterministically.
      Pair it with a short, concrete failureReason describing the blocker and
      what would be needed to resolve it. "failed" items are terminal for the
      current run — do not retry them, continue with the remaining items.
    `,
        inputSchema: z.object({
            action: z
                .enum(["add", "update", "get"])
                .describe("Action to perform on the checklist"),
            itemId: z
                .string()
                .optional()
                .describe("ID of the item to update (required for update action)"),
            content: z
                .string()
                .optional()
                .describe("Content/description of the checklist item"),
            status: z
                .enum(["pending", "in_progress", "completed", "cancelled", "failed"])
                .optional()
                .describe("Status of the checklist item"),
            failureReason: z
                .string()
                .optional()
                .describe("Short, concrete explanation of why the task failed. Only meaningful when status is 'failed'."),
        }),
        execute: async ({ action, itemId, content, status, failureReason }) => {
            const useMigrationChecklist = await isMigrationChecklistActive(services.appRootDirPath);
            const checklistState = useMigrationChecklist
                ? null
                : getChecklistState(clark);
            switch (action) {
                case "add": {
                    if (!content) {
                        throw new Error("Content is required when adding a checklist item");
                    }
                    let newItem;
                    let totalItems;
                    if (useMigrationChecklist) {
                        const migrationResult = await addMigrationChecklistItem({
                            appRootDirPath: services.appRootDirPath,
                            content,
                            status: status || "pending",
                        });
                        newItem = migrationResult.item;
                        totalItems = migrationResult.state.items.length;
                    }
                    else {
                        newItem = {
                            id: `item_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
                            content,
                            status: status || "pending",
                            createdAt: new Date().toISOString(),
                            ...(status === "failed" && failureReason
                                ? { failureReason }
                                : {}),
                        };
                        const newState = {
                            ...checklistState,
                            items: [...checklistState.items, newItem],
                        };
                        totalItems = newState.items.length;
                        updateChecklistState(clark, newState);
                    }
                    // Notify UI about the new item
                    await services.appShell.sendMessage({
                        type: "checklist_item_added",
                        payload: {
                            item: newItem,
                            totalItems,
                        },
                    });
                    return {
                        success: true,
                        action: "add",
                        item: newItem,
                        message: `Added checklist item: "${content}"`,
                        totalItems,
                    };
                }
                case "update": {
                    if (!itemId) {
                        throw new Error("Item ID is required when updating a checklist item");
                    }
                    let updatedItem;
                    let completedItems;
                    let totalItems;
                    if (useMigrationChecklist) {
                        const migrationResult = await updateMigrationChecklistItem({
                            appRootDirPath: services.appRootDirPath,
                            itemId,
                            content,
                            status,
                            failureReason,
                        });
                        updatedItem = migrationResult.item;
                        completedItems = migrationResult.state.items.filter((item) => item.status === "completed").length;
                        totalItems = migrationResult.state.items.length;
                    }
                    else {
                        const itemIndex = checklistState.items.findIndex((item) => item.id === itemId);
                        if (itemIndex === -1) {
                            throw new Error(`Checklist item with ID "${itemId}" not found`);
                        }
                        const existingItem = checklistState.items[itemIndex];
                        if (!existingItem) {
                            throw new Error(`Checklist item at index ${itemIndex} is undefined`);
                        }
                        const nextStatus = status || existingItem.status;
                        updatedItem = {
                            id: existingItem.id,
                            content: content || existingItem.content,
                            status: nextStatus,
                            createdAt: existingItem.createdAt,
                            updatedAt: new Date().toISOString(),
                            failureReason: nextStatus === "failed"
                                ? (failureReason ?? existingItem.failureReason)
                                : undefined,
                        };
                        const newItems = [...checklistState.items];
                        newItems[itemIndex] = updatedItem;
                        const newState = {
                            ...checklistState,
                            items: newItems,
                        };
                        completedItems = newState.items.filter((item) => item.status === "completed").length;
                        totalItems = newState.items.length;
                        updateChecklistState(clark, newState);
                    }
                    // Notify UI about the updated item
                    await services.appShell.sendMessage({
                        type: "checklist_item_updated",
                        payload: {
                            item: updatedItem,
                            completedItems,
                            totalItems,
                        },
                    });
                    return {
                        success: true,
                        action: "update",
                        item: updatedItem,
                        message: `Updated checklist item: "${updatedItem.content}"`,
                        completedItems,
                        totalItems,
                    };
                }
                case "get": {
                    const stateForGet = useMigrationChecklist
                        ? await readMigrationChecklist(services.appRootDirPath)
                        : checklistState;
                    const items = stateForGet?.items ?? [];
                    const completedItems = items.filter((item) => item.status === "completed").length;
                    return {
                        success: true,
                        action: "get",
                        items,
                        completedItems,
                        totalItems: items.length,
                        lastUpdated: stateForGet?.lastUpdated,
                        message: `Retrieved ${items.length} checklist items`,
                    };
                }
                default:
                    throw new Error(`Unknown action: ${action}`);
            }
        },
        getSummary: (input, output) => {
            const action = input.action;
            const totalItems = output.totalItems ?? 0;
            const completedItems = output.completedItems ?? 0;
            return {
                input: `action: ${action}`,
                output: `${completedItems}/${totalItems} complete`,
            };
        },
    };
});
//# sourceMappingURL=build-manage-checklist.js.map