import { Paths } from "../../const.js";
import { getIntegrationErrorsInFiles } from "../../integration-validator.js";
import { matchMultiplePaths, matchPath } from "../../transform/shared.js";
import { APP_RUNTIME_UPDATED_WITHOUT_EDITS, POST_PROCESSING_FINISHED, RUNTIME_REVIEW_ERRORED, RUNTIME_REVIEW_FINISHED, USER_REJECTED_DRAFT, } from "../clark-fsm.js";
import { sendChangeInfoHelper } from "../helpers/change-info.js";
import { sendUserMessageChannel } from "../helpers/peer.js";
import { transitionFrom } from "../helpers/transition.js";
export const doRuntimeReviewing = (clark, params) => {
    const transitionTo = transitionFrom(clark);
    const sendChangeInfo = sendChangeInfoHelper(clark, params.chatSessionStore);
    const sendUserMessage = sendUserMessageChannel(clark, params.chatSessionStore);
    return async ({ event }) => {
        switch (event.type) {
            case USER_REJECTED_DRAFT:
                console.log(`[doRuntimeReviewing] USER_REJECTED_DRAFT`, event);
                if (!event.silently) {
                    const chatmessageId = await params.chatSessionStore.recordUserRejection();
                    if (chatmessageId) {
                        clark.updateContext({
                            chatmessageId,
                        });
                    }
                }
                await params.appShell.clearScratchDirectory();
                // the draft is reverting now...
                void transitionTo({
                    type: APP_RUNTIME_UPDATED_WITHOUT_EDITS,
                });
                break;
            case POST_PROCESSING_FINISHED:
                {
                    const { files } = event;
                    // AI-1053: always use debug loop for now
                    // const useDebugLoop =
                    //   await clark.context.promptInterpretTask?.isFullAppOrBroadUpdate();
                    const useDebugLoop = true;
                    clark.updateContext((context) => ({
                        ...context,
                        hasSuggestions: context.hasSuggestions || files.length > 0,
                    }));
                    if (!useDebugLoop) {
                        for (const filePath of Object.keys(clark.context.generatedChangeInfo ?? {})) {
                            void sendChangeInfo({
                                type: "validated",
                                filePath,
                            });
                        }
                        void transitionTo({
                            type: RUNTIME_REVIEW_FINISHED,
                        });
                        break;
                    }
                    if (!clark.context.usedDebugging) {
                        void sendUserMessage({
                            type: "text",
                            role: "assistant",
                            group: "agent-qa",
                            content: "Great, I'll confirm this app works as expected.",
                        });
                    }
                    void sendUserMessage({
                        type: "control",
                        role: "assistant",
                        group: "agent-qa/code-errors",
                        status: "pending",
                        content: "Identifying code errors",
                    });
                    void sendUserMessage({
                        type: "control",
                        role: "assistant",
                        group: "agent-qa/user-flows",
                        status: "pending",
                        content: "Validating user flows",
                    });
                    void sendUserMessage({
                        type: "control",
                        role: "assistant",
                        group: "agent-qa/design-system",
                        status: "pending",
                        content: "Validating design system adherence",
                    });
                    const lintable = matchMultiplePaths(Paths.PageIndexes, Paths.ComponentsFile, Paths.ComponentsFolder, Paths.AppScope, Paths.PageScopes);
                    const lintErrorsByPath = await params.appShell.runLinter(files
                        .map((file) => file.filePath)
                        .filter((filePath) => lintable(filePath).matched), clark.context.abortController?.signal);
                    // n.b. don't race these because we want to typecheck after potential lint autofixes
                    const tsErrorsByPath = await params.appShell.runTypecheck(clark.context.abortController?.signal);
                    // Validate integration references - only on API files
                    const availableIntegrations = clark.context.availableIntegrations ?? [];
                    const apiMatcher = matchPath(Paths.GeneratedApis);
                    const apiFiles = files.filter((file) => apiMatcher(file.filePath).matched);
                    const integrationErrorsByPath = getIntegrationErrorsInFiles(apiFiles, availableIntegrations);
                    if (tsErrorsByPath || lintErrorsByPath || integrationErrorsByPath) {
                        void transitionTo({
                            type: RUNTIME_REVIEW_ERRORED,
                            tsErrorsByPath: tsErrorsByPath ?? {},
                            lintErrorsByPath: lintErrorsByPath ?? {},
                            integrationErrorsByPath: integrationErrorsByPath ?? {},
                        });
                    }
                    else {
                        for (const filePath of Object.keys(clark.context.generatedChangeInfo ?? {})) {
                            void sendChangeInfo({
                                type: "validated",
                                filePath,
                            });
                        }
                        let delay = 500;
                        if (clark.context.usedDebugging) {
                            void sendUserMessage({
                                type: "text",
                                role: "assistant",
                                group: "agent-qa",
                                content: "Looks like the Engineer Agent has fixed the bugs I've reported. We're good to go!",
                            });
                            delay = 0;
                        }
                        void sendUserMessage({
                            type: "control",
                            role: "assistant",
                            group: "agent-qa/code-errors",
                            status: "validated",
                            content: "Identifying code errors",
                        }, delay);
                        void sendUserMessage({
                            type: "control",
                            role: "assistant",
                            group: "agent-qa/user-flows",
                            status: "validated",
                            content: "Validating user flows",
                        }, delay + 500);
                        void sendUserMessage({
                            type: "control",
                            role: "assistant",
                            group: "agent-qa/design-system",
                            status: "validated",
                            content: "Validating design system adherence",
                        }, delay + 1000);
                        void transitionTo({
                            type: RUNTIME_REVIEW_FINISHED,
                        });
                    }
                }
                break;
            default:
                throw new Error(`Unhandled event: ${event}`);
        }
    };
};
//# sourceMappingURL=runtime-reviewing.js.map