import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useState, useCallback } from 'react';
import { Box, Text, useStdin } from 'ink';
import { ApprovalMode, validatePlanPath, validatePlanContent, QuestionType, processSingleFileContent, debugLogger, } from '@google/gemini-cli-core';
import { theme } from '../semantic-colors.js';
import { useConfig } from '../contexts/ConfigContext.js';
import { AskUserDialog } from './AskUserDialog.js';
import { openFileInEditor } from '../utils/editorUtils.js';
import { useKeypress } from '../hooks/useKeypress.js';
import { keyMatchers, Command } from '../keyMatchers.js';
import { formatCommand } from '../utils/keybindingUtils.js';
var PlanStatus;
(function (PlanStatus) {
    PlanStatus["Loading"] = "loading";
    PlanStatus["Loaded"] = "loaded";
    PlanStatus["Error"] = "error";
})(PlanStatus || (PlanStatus = {}));
var ApprovalOption;
(function (ApprovalOption) {
    ApprovalOption["Auto"] = "Yes, automatically accept edits";
    ApprovalOption["Manual"] = "Yes, manually accept edits";
})(ApprovalOption || (ApprovalOption = {}));
/**
 * A tiny component for loading and error states with consistent styling.
 */
const StatusMessage = ({ children }) => _jsx(Box, { paddingX: 1, children: children });
function usePlanContent(planPath, config) {
    const [version, setVersion] = useState(0);
    const [state, setState] = useState({
        status: PlanStatus.Loading,
    });
    const refresh = useCallback(() => {
        setVersion((v) => v + 1);
    }, []);
    useEffect(() => {
        let ignore = false;
        setState({ status: PlanStatus.Loading });
        const load = async () => {
            try {
                const pathError = await validatePlanPath(planPath, config.storage.getPlansDir(), config.getTargetDir());
                if (ignore)
                    return;
                if (pathError) {
                    setState({ status: PlanStatus.Error, error: pathError });
                    return;
                }
                const contentError = await validatePlanContent(planPath);
                if (ignore)
                    return;
                if (contentError) {
                    setState({ status: PlanStatus.Error, error: contentError });
                    return;
                }
                const result = await processSingleFileContent(planPath, config.storage.getPlansDir(), config.getFileSystemService());
                if (ignore)
                    return;
                if (result.error) {
                    setState({ status: PlanStatus.Error, error: result.error });
                    return;
                }
                if (typeof result.llmContent !== 'string') {
                    setState({
                        status: PlanStatus.Error,
                        error: 'Plan file format not supported (binary or image).',
                    });
                    return;
                }
                const content = result.llmContent;
                if (!content) {
                    setState({ status: PlanStatus.Error, error: 'Plan file is empty.' });
                    return;
                }
                setState({ status: PlanStatus.Loaded, content });
            }
            catch (err) {
                if (ignore)
                    return;
                const errorMessage = err instanceof Error ? err.message : String(err);
                setState({ status: PlanStatus.Error, error: errorMessage });
            }
        };
        void load();
        return () => {
            ignore = true;
        };
    }, [planPath, config, version]);
    return { ...state, refresh };
}
export const ExitPlanModeDialog = ({ planPath, onApprove, onFeedback, onCancel, getPreferredEditor, width, availableHeight, }) => {
    const config = useConfig();
    const { stdin, setRawMode } = useStdin();
    const planState = usePlanContent(planPath, config);
    const { refresh } = planState;
    const [showLoading, setShowLoading] = useState(false);
    const handleOpenEditor = useCallback(async () => {
        try {
            await openFileInEditor(planPath, stdin, setRawMode, getPreferredEditor());
            onFeedback('I have edited the plan or annotated it with feedback. Review the edited plan, update if necessary, and present it again for approval.');
            refresh();
        }
        catch (err) {
            debugLogger.error('Failed to open plan in editor:', err);
        }
    }, [planPath, stdin, setRawMode, getPreferredEditor, refresh, onFeedback]);
    useKeypress((key) => {
        if (keyMatchers[Command.OPEN_EXTERNAL_EDITOR](key)) {
            void handleOpenEditor();
            return true;
        }
        return false;
    }, { isActive: true, priority: true });
    useEffect(() => {
        if (planState.status !== PlanStatus.Loading) {
            setShowLoading(false);
            return;
        }
        const timer = setTimeout(() => {
            setShowLoading(true);
        }, 200);
        return () => clearTimeout(timer);
    }, [planState.status]);
    if (planState.status === PlanStatus.Loading) {
        if (!showLoading) {
            return null;
        }
        return (_jsx(StatusMessage, { children: _jsx(Text, { color: theme.text.secondary, italic: true, children: "Loading plan..." }) }));
    }
    if (planState.status === PlanStatus.Error) {
        return (_jsx(StatusMessage, { children: _jsxs(Text, { color: theme.status.error, children: ["Error reading plan: ", planState.error] }) }));
    }
    const planContent = planState.content?.trim();
    if (!planContent) {
        return (_jsx(StatusMessage, { children: _jsx(Text, { color: theme.status.error, children: "Error: Plan content is empty." }) }));
    }
    const editHint = formatCommand(Command.OPEN_EXTERNAL_EDITOR);
    return (_jsx(Box, { flexDirection: "column", width: width, children: _jsx(AskUserDialog, { questions: [
                {
                    type: QuestionType.CHOICE,
                    header: 'Approval',
                    question: planContent,
                    options: [
                        {
                            label: ApprovalOption.Auto,
                            description: 'Approves plan and allows tools to run automatically',
                        },
                        {
                            label: ApprovalOption.Manual,
                            description: 'Approves plan but requires confirmation for each tool',
                        },
                    ],
                    placeholder: 'Type your feedback...',
                    multiSelect: false,
                    unconstrainedHeight: false,
                },
            ], onSubmit: (answers) => {
                const answer = answers['0'];
                if (answer === ApprovalOption.Auto) {
                    onApprove(ApprovalMode.AUTO_EDIT);
                }
                else if (answer === ApprovalOption.Manual) {
                    onApprove(ApprovalMode.DEFAULT);
                }
                else if (answer) {
                    onFeedback(answer);
                }
            }, onCancel: onCancel, width: width, availableHeight: availableHeight, extraParts: [`${editHint} to edit plan`] }) }));
};
//# sourceMappingURL=ExitPlanModeDialog.js.map