import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { spawnSync } from 'node:child_process';
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from 'node:fs';
import { dirname, join } from 'node:path';
import { Box, Text, useFocus, useInput } from 'ink';
import SelectInput from 'ink-select-input';
import Spinner from 'ink-spinner';
import { useEffect, useState } from 'react';
import { TitledBoxWithPreferences } from '../components/ui/titled-box.js';
import { colors } from '../config/index.js';
import { getConfigPath } from '../config/paths.js';
import { useResponsiveTerminal } from '../hooks/useTerminalWidth.js';
import { logError, logInfo } from '../utils/message-queue.js';
import { LocationStep } from './steps/location-step.js';
import { ProviderStep } from './steps/provider-step.js';
import { buildProviderConfigObject } from './validation.js';
export function ProviderWizard({ projectDir, onComplete, onCancel, }) {
    const [step, setStep] = useState('location');
    const [providerConfigPath, setProviderConfigPath] = useState('');
    const [providers, setProviders] = useState([]);
    const [error, setError] = useState(null);
    const { boxWidth, isNarrow } = useResponsiveTerminal();
    // Capture focus to ensure keyboard handling works properly
    useFocus({ autoFocus: true, id: 'config-wizard' });
    // Load existing config if editing
    useEffect(() => {
        if (!providerConfigPath) {
            return;
        }
        // Use a microtask to defer state updates
        void Promise.resolve().then(() => {
            try {
                let loadedProviders = [];
                // Try to load providers from agents.config.json
                if (existsSync(providerConfigPath)) {
                    try {
                        const providerContent = readFileSync(providerConfigPath, 'utf-8');
                        const providerConfig = JSON.parse(providerContent);
                        loadedProviders = providerConfig.nanocoder?.providers || [];
                    }
                    catch (err) {
                        logError('Failed to load provider configuration', true, {
                            context: { providerConfigPath },
                            error: err instanceof Error ? err.message : String(err),
                        });
                    }
                }
                setProviders(loadedProviders);
            }
            catch (err) {
                logError('Failed to load existing configuration', true, {
                    context: { providerConfigPath },
                    error: err instanceof Error ? err.message : String(err),
                });
            }
        });
    }, [providerConfigPath]);
    const handleLocationComplete = (location) => {
        // Determine the base directory based on location
        const baseDir = location === 'project' ? process.cwd() : getConfigPath();
        setProviderConfigPath(join(baseDir, 'agents.config.json'));
        setStep('providers');
    };
    const handleProvidersComplete = (newProviders) => {
        setProviders(newProviders);
        setStep('summary');
    };
    const handleSave = () => {
        setStep('saving');
        setError(null);
        try {
            // Build and save provider config
            if (providers.length > 0) {
                const providerConfig = buildProviderConfigObject(providers);
                const providerDir = dirname(providerConfigPath);
                if (!existsSync(providerDir)) {
                    mkdirSync(providerDir, { recursive: true });
                }
                writeFileSync(providerConfigPath, JSON.stringify(providerConfig, null, 2), 'utf-8');
            }
            setStep('complete');
            // Don't auto-complete - wait for user to press Enter
        }
        catch (err) {
            setError(err instanceof Error ? err.message : 'Failed to save configuration');
            setStep('summary');
        }
    };
    const handleAddProviders = () => {
        setStep('providers');
    };
    const handleCancel = () => {
        if (onCancel) {
            onCancel();
        }
    };
    const handleDeleteConfig = () => {
        setStep('confirm-delete');
    };
    const handleConfirmDelete = () => {
        try {
            if (existsSync(providerConfigPath)) {
                unlinkSync(providerConfigPath);
                logInfo(`Deleted configuration file: ${providerConfigPath}`);
            }
            // Call onComplete to trigger reload
            onComplete(providerConfigPath);
        }
        catch (err) {
            setError(err instanceof Error ? err.message : 'Failed to delete configuration');
            setStep('providers');
        }
    };
    const openInEditor = () => {
        try {
            // Save current progress
            if (providers.length > 0) {
                const providerConfig = buildProviderConfigObject(providers);
                const providerDir = dirname(providerConfigPath);
                if (!existsSync(providerDir)) {
                    mkdirSync(providerDir, { recursive: true });
                }
                writeFileSync(providerConfigPath, JSON.stringify(providerConfig, null, 2), 'utf-8');
            }
            // Detect editor (respect $EDITOR or $VISUAL environment variables)
            // Fall back to nano on Unix/Mac (much friendlier than vi!)
            // On Windows, use notepad
            const editor = process.env.EDITOR ||
                process.env.VISUAL ||
                (process.platform === 'win32' ? 'notepad' : 'nano');
            // Show cursor and restore terminal for editor
            process.stdout.write('\x1B[?25h'); // Show cursor
            process.stdin.setRawMode?.(false); // Disable raw mode
            // Open provider config in editor
            const result = spawnSync(editor, [providerConfigPath], {
                stdio: 'inherit', // Give editor full control of terminal
            });
            // Restore terminal state after editor closes
            process.stdin.setRawMode?.(true); // Re-enable raw mode
            process.stdout.write('\x1B[?25l'); // Hide cursor (Ink will manage it)
            if (result.status === 0) {
                // Reload config to get updated values
                let loadedProviders = [];
                // Reload provider config
                if (existsSync(providerConfigPath)) {
                    try {
                        const editedContent = readFileSync(providerConfigPath, 'utf-8');
                        const editedConfig = JSON.parse(editedContent);
                        loadedProviders = editedConfig.nanocoder?.providers || [];
                    }
                    catch (parseErr) {
                        setError(parseErr instanceof Error
                            ? `Invalid JSON: ${parseErr.message}`
                            : 'Failed to parse edited configuration');
                        setStep('summary');
                        return;
                    }
                }
                setProviders(loadedProviders);
                // Return to summary to review changes
                setStep('summary');
                setError(null);
            }
            else {
                setError('Editor exited with an error. Changes may not be saved.');
                setStep('summary');
            }
        }
        catch (err) {
            // Restore terminal state on error
            process.stdin.setRawMode?.(true);
            process.stdout.write('\x1B[?25l');
            setError(err instanceof Error
                ? `Failed to open editor: ${err.message}`
                : 'Failed to open editor');
            setStep('summary');
        }
    };
    // Handle global keyboard shortcuts
    useInput((input, key) => {
        // In complete step, wait for Enter to finish
        if (step === 'complete' && key.return) {
            onComplete(providerConfigPath);
            return;
        }
        // Escape - cancel/exit wizard completely
        if (key.escape) {
            if (onCancel) {
                onCancel();
            }
            return;
        }
        // Ctrl+E to open editor (available after location is chosen)
        if (key.ctrl &&
            input === 'e' &&
            providerConfigPath &&
            (step === 'providers' || step === 'summary')) {
            openInEditor();
        }
    });
    const renderStep = () => {
        switch (step) {
            case 'location': {
                return (_jsx(LocationStep, { projectDir: projectDir, onComplete: handleLocationComplete, onBack: onCancel }));
            }
            case 'providers': {
                return (_jsx(ProviderStep, { existingProviders: providers, onComplete: handleProvidersComplete, onBack: () => setStep('location'), onDelete: handleDeleteConfig, configExists: existsSync(providerConfigPath) }));
            }
            case 'summary': {
                return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: colors.primary, children: "Configuration Summary" }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.secondary, children: "Config file:" }), _jsx(Text, { color: colors.success, children: providerConfigPath })] }), providers.length > 0 ? (_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsxs(Text, { color: colors.secondary, children: ["Providers (", providers.length, "):"] }), providers.map((provider, index) => (_jsxs(Text, { color: colors.success, children: ["\u2022 ", provider.name] }, index)))] })) : (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.warning, children: "No providers configured" }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.secondary, children: "\u2022 Enter: Save configuration" }), _jsx(Text, { color: colors.secondary, children: "\u2022 Shift+Tab: Go back" }), _jsx(Text, { color: colors.secondary, children: "\u2022 Esc: Cancel" })] })] }));
            }
            case 'confirm-delete': {
                const deleteOptions = [
                    { label: 'Yes, delete the file', value: 'yes' },
                    { label: 'No, go back', value: 'no' },
                ];
                return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: colors.error, children: "Delete Configuration?" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Are you sure you want to delete", ' ', _jsx(Text, { color: colors.warning, children: providerConfigPath }), "?"] }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "This action cannot be undone." }) }), _jsx(SelectInput, { items: deleteOptions, onSelect: (item) => {
                                if (item.value === 'yes') {
                                    handleConfirmDelete();
                                }
                                else {
                                    setStep('providers');
                                }
                            } })] }));
            }
            case 'saving': {
                return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { children: _jsxs(Text, { color: colors.success, children: [_jsx(Spinner, { type: "dots" }), " Saving configuration..."] }) }) }));
            }
            case 'complete': {
                return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.success, bold: true, children: "\u2713 Configuration saved!" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Saved to:" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: [" ", providerConfigPath] }) }), _jsx(Box, { children: _jsx(Text, { color: colors.secondary, children: "Press Enter to continue" }) })] }));
            }
            default: {
                return null;
            }
        }
    };
    return (_jsxs(TitledBoxWithPreferences, { title: "Provider Wizard", reversePowerline: true, width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: colors.error, children: ["Error: ", error] }) })), renderStep(), (step === 'location' || step === 'providers' || step === 'summary') &&
                (isNarrow ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.secondary, children: "Esc: Exit wizard" }), _jsx(Text, { color: colors.secondary, children: "Shift+Tab: Go back" }), providerConfigPath && (_jsx(Text, { color: colors.secondary, children: "Ctrl+E: Edit manually" }))] })) : (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.secondary, children: ["Esc: Exit wizard | Shift+Tab: Go back", providerConfigPath && ' | Ctrl+E: Edit manually'] }) }))), step === 'summary' && (_jsx(SummaryStepActions, { onSave: handleSave, onAddProviders: handleAddProviders, onCancel: handleCancel }))] }));
}
function SummaryStepActions({ onSave, onAddProviders, onCancel, }) {
    useInput((_input, key) => {
        if (key.shift && key.tab) {
            onAddProviders();
        }
        else if (key.return) {
            onSave();
        }
        else if (key.escape) {
            onCancel();
        }
    });
    return null;
}
//# sourceMappingURL=provider-wizard.js.map