import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { useState, useEffect, useMemo } from 'react';
import { Box, Text } from 'ink';
import { SemanticColors } from '../colors.js';
import { useResponsive } from '../hooks/useResponsive.js';
import { useKeypress } from '../hooks/useKeypress.js';
/**
 * Validates a profile structure. Returns error message or null if valid.
 */
function validateProfile(profile) {
    if (typeof profile !== 'object' || profile === null) {
        return 'Invalid profile: must be an object';
    }
    const p = profile;
    if (!('version' in p) || typeof p.version !== 'string') {
        return 'Missing or invalid version';
    }
    if (!('type' in p) || typeof p.type !== 'string') {
        return 'Missing or invalid type';
    }
    if (p.type === 'standard') {
        if (!('provider' in p) || typeof p.provider !== 'string' || !p.provider) {
            return 'Standard profile requires provider';
        }
        if (!('model' in p) || typeof p.model !== 'string' || !p.model) {
            return 'Standard profile requires model';
        }
    }
    else if (p.type === 'loadbalancer') {
        if (!('profiles' in p) || !Array.isArray(p.profiles)) {
            return 'Load balancer requires profiles array';
        }
        if (p.profiles.length === 0) {
            return 'Load balancer requires at least one profile';
        }
        if (!p.profiles.every((item) => typeof item === 'string')) {
            return 'Profiles must be strings';
        }
        if (!('policy' in p) || typeof p.policy !== 'string' || !p.policy) {
            return 'Load balancer requires policy';
        }
    }
    else {
        return `Unknown profile type: ${p.type}`;
    }
    return null;
}
// Simple JSON editor that allows line-by-line editing
export const ProfileInlineEditor = ({ profileName, profile, onSave, onCancel, error: externalError, }) => {
    const { width } = useResponsive();
    // Convert profile to formatted JSON lines
    const formatProfile = (p) => {
        const json = JSON.stringify(p, null, 2);
        return json.split('\n');
    };
    const [lines, setLines] = useState(() => formatProfile(profile));
    const [cursorLine, setCursorLine] = useState(0);
    const [isEditing, setIsEditing] = useState(false);
    const [editBuffer, setEditBuffer] = useState('');
    const [validationError, setValidationError] = useState(null);
    const [hasChanges, setHasChanges] = useState(false);
    // Visible window for scrolling
    const maxVisibleLines = 15;
    const [scrollOffset, setScrollOffset] = useState(0);
    // Reset editor when a different profile is loaded into the dialog.
    useEffect(() => {
        setLines(formatProfile(profile));
        setCursorLine(0);
        setScrollOffset(0);
        setIsEditing(false);
        setEditBuffer('');
        setValidationError(null);
        setHasChanges(false);
    }, [profileName, profile]);
    // Ensure cursor line is visible
    useEffect(() => {
        if (cursorLine < scrollOffset) {
            setScrollOffset(cursorLine);
        }
        else if (cursorLine >= scrollOffset + maxVisibleLines) {
            setScrollOffset(cursorLine - maxVisibleLines + 1);
        }
    }, [cursorLine, scrollOffset, maxVisibleLines]);
    // Validate JSON on changes
    const validateJson = useMemo(() => {
        try {
            const jsonString = lines.join('\n');
            JSON.parse(jsonString);
            return null;
        }
        catch (e) {
            return e instanceof Error ? e.message : 'Invalid JSON';
        }
    }, [lines]);
    // Clear stale validation errors when JSON becomes valid
    useEffect(() => {
        if (!validateJson) {
            setValidationError(null);
        }
    }, [validateJson]);
    useKeypress((key) => {
        if (isEditing) {
            // Edit mode
            if (key.name === 'escape') {
                // Cancel line edit
                setIsEditing(false);
                setEditBuffer('');
                return;
            }
            if (key.name === 'return') {
                // Commit line edit
                const newLines = [...lines];
                newLines[cursorLine] = editBuffer;
                setLines(newLines);
                setIsEditing(false);
                setEditBuffer('');
                setHasChanges(true);
                return;
            }
            if (key.name === 'backspace' || key.name === 'delete') {
                setEditBuffer((prev) => prev.slice(0, -1));
                return;
            }
            if (typeof key.sequence === 'string' &&
                !key.ctrl &&
                !key.meta &&
                key.sequence.length === 1) {
                setEditBuffer((prev) => prev + key.sequence);
                return;
            }
            return;
        }
        // Navigation mode
        if (key.name === 'escape') {
            onCancel();
            return;
        }
        // Save
        if (key.ctrl && key.name === 's') {
            if (validateJson) {
                setValidationError(validateJson);
                return;
            }
            try {
                const updatedProfile = JSON.parse(lines.join('\n'));
                // Comprehensive profile validation
                const profileError = validateProfile(updatedProfile);
                if (profileError) {
                    setValidationError(profileError);
                    return;
                }
                onSave(profileName, updatedProfile);
            }
            catch (e) {
                setValidationError(e instanceof Error ? e.message : 'Invalid JSON');
            }
            return;
        }
        // Navigation
        if (key.name === 'up' || key.sequence === 'k') {
            setCursorLine((prev) => Math.max(0, prev - 1));
            return;
        }
        if (key.name === 'down' || key.sequence === 'j') {
            setCursorLine((prev) => Math.min(lines.length - 1, prev + 1));
            return;
        }
        // Enter edit mode
        if (key.name === 'return' || key.sequence === 'e') {
            setIsEditing(true);
            setEditBuffer(lines[cursorLine]);
            setValidationError(null);
            return;
        }
        // Page up/down
        if (key.name === 'pageup') {
            setCursorLine((prev) => Math.max(0, prev - maxVisibleLines));
            return;
        }
        if (key.name === 'pagedown') {
            setCursorLine((prev) => Math.min(lines.length - 1, prev + maxVisibleLines));
            return;
        }
        // Home/End
        if (key.sequence === 'g') {
            setCursorLine(0);
            return;
        }
        if (key.sequence === 'G') {
            setCursorLine(lines.length - 1);
            return;
        }
    }, { isActive: true });
    const visibleLines = lines.slice(scrollOffset, scrollOffset + maxVisibleLines);
    const dialogWidth = Math.min(width, 90);
    return (_jsxs(Box, { borderStyle: "round", borderColor: validateJson
            ? SemanticColors.status.error
            : hasChanges
                ? SemanticColors.status.warning
                : SemanticColors.border.default, flexDirection: "column", padding: 1, width: dialogWidth, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { bold: true, color: SemanticColors.text.accent, children: ["Edit: ", profileName] }), hasChanges && (_jsx(Text, { color: SemanticColors.status.warning, children: " (modified)" }))] }), (validationError || externalError || validateJson) && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: SemanticColors.status.error, children: ["Error: ", validationError || externalError || validateJson] }) })), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: visibleLines.map((line, idx) => {
                    const actualLine = scrollOffset + idx;
                    const isCurrentLine = actualLine === cursorLine;
                    return (_jsxs(Box, { children: [_jsx(Box, { width: 4, children: _jsx(Text, { color: isCurrentLine
                                        ? SemanticColors.text.accent
                                        : SemanticColors.text.secondary, children: String(actualLine + 1).padStart(3, ' ') }) }), isEditing && isCurrentLine ? (_jsx(Box, { children: _jsxs(Text, { color: SemanticColors.text.accent, children: [editBuffer, _jsx(Text, { color: SemanticColors.text.accent, children: "\u258C" })] }) })) : (_jsxs(Text, { color: isCurrentLine
                                    ? SemanticColors.text.accent
                                    : SemanticColors.text.primary, bold: isCurrentLine, children: [isCurrentLine ? '› ' : '  ', line] }))] }, actualLine));
                }) }), lines.length > maxVisibleLines && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: SemanticColors.text.secondary, children: ["Lines ", scrollOffset + 1, "-", Math.min(scrollOffset + maxVisibleLines, lines.length), " of", ' ', lines.length] }) })), _jsx(Box, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: SemanticColors.border.default, paddingTop: 1, children: isEditing ? (_jsxs(Text, { color: SemanticColors.text.secondary, children: ["Editing line ", cursorLine + 1, ". Enter=commit, Esc=cancel"] })) : (_jsx(Text, { color: SemanticColors.text.secondary, children: "\u2191/\u2193=navigate, Enter/e=edit line, Ctrl+S=save, Esc=cancel" })) })] }));
};
//# sourceMappingURL=ProfileInlineEditor.js.map