import { r as registerInstance, c as createEvent, h } from './index-BIwHMk6j.js';
import { L as Le } from './index.esm-CMeGYws2.js';
import { v as validateResponseFormatOnly } from './lime-query-validation-DvCLebd2.js';
import './property-resolution-CQUZjrU4.js';

/**
 * Helper functions for working with ResponseFormat objects
 *
 * These utilities handle parsing, stringifying, and default values
 * for ResponseFormat in isolation (without full LimeQuery wrapper)
 */
/**
 * Parse JSON string to ResponseFormat
 *
 * @param json - JSON string to parse
 * @returns Parsed ResponseFormat object
 * @throws Error if JSON is invalid or not a ResponseFormat
 */
function parseResponseFormat(json) {
    let parsed;
    try {
        parsed = JSON.parse(json);
    }
    catch (error) {
        throw new Error(`Invalid JSON: ${error.message}`);
    }
    if (parsed === null || typeof parsed !== 'object') {
        throw new Error('Response format must be an object');
    }
    // Validate structure
    const validKeys = new Set(['object', 'aggregates']);
    const keys = Object.keys(parsed);
    // Check for unexpected keys
    const unexpectedKeys = keys.filter((key) => !validKeys.has(key));
    if (unexpectedKeys.length > 0) {
        throw new Error(`Unexpected properties in response format: ${unexpectedKeys.join(', ')}. ` +
            `Only 'object' and 'aggregates' are allowed.`);
    }
    // Must have at least one of object or aggregates
    // Note: Empty objects {} are valid (starting point for visual mode)
    const hasProperties = keys.length > 0;
    if (hasProperties && !parsed.object && !parsed.aggregates) {
        throw new Error('Response format must contain at least one of: object, aggregates');
    }
    return parsed;
}
/**
 * Stringify ResponseFormat to JSON
 *
 * @param format - ResponseFormat object to stringify
 * @returns Pretty-printed JSON string
 */
function stringifyResponseFormat(format) {
    return JSON.stringify(format, null, 2);
}
/**
 * Get default ResponseFormat (just _id)
 *
 * @returns Default ResponseFormat with only _id selected
 */
function getDefaultResponseFormat() {
    return {
        object: {
            _id: null,
        },
    };
}

const limeQueryResponseFormatBuilderCss = () => `:host(limebb-lime-query-response-format-builder){display:block;width:100%}.response-format-builder{display:flex;flex-direction:column}.builder-label{color:rgb(var(--contrast-1100));font-size:1.625rem;line-height:1.25rem;font-weight:300;margin-top:1rem;margin-bottom:0.25rem}.builder-helper-text{margin-top:0px;margin-bottom:0.5rem;font-size:var(--limel-theme-default-font-size);color:rgb(var(--contrast-1100))}.mode-controls{display:flex;justify-content:flex-end;padding:0.5rem}.visual-mode,.code-mode{display:block}.code-editor-container{--code-editor-max-height:70vh;display:flex;flex-direction:column;gap:1rem}.code-editor-container .validation-errors{padding:0.75rem 1rem;color:rgb(var(--color-red-default));background-color:rgb(var(--color-red-lighter));border-left:0.25rem solid rgb(var(--color-red-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .validation-errors strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .validation-errors ul{margin:0;padding-left:1.5rem}.code-editor-container .validation-errors li{margin:0.25rem 0}.code-editor-container .visual-mode-limitations{padding:0.75rem 1rem;color:rgb(var(--color-blue-dark));background-color:rgb(var(--color-blue-lighter));border-left:0.25rem solid rgb(var(--color-blue-default));border-radius:0.25rem;font-size:0.875rem}.code-editor-container .visual-mode-limitations strong{display:block;margin-bottom:0.5rem;font-weight:600}.code-editor-container .visual-mode-limitations ul{margin:0;padding-left:1.5rem}.code-editor-container .visual-mode-limitations li{margin:0.25rem 0}`;

var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
        r = Reflect.decorate(decorators, target, key, desc);
    else
        for (var i = decorators.length - 1; i >= 0; i--)
            if (d = decorators[i])
                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const LimeQueryResponseFormatBuilder = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.change = createEvent(this, "change");
        /**
         * Optional label for the builder
         */
        this.label = 'Response Format';
        /**
         * Optional helper text for the builder
         */
        this.helperText = '';
        this.mode = 'visual';
        this.codeValue = '';
        this.handleModeChange = (event) => {
            event.stopPropagation();
            const mode = event.detail.id;
            if (mode === 'visual') {
                this.switchToVisualMode();
            }
            else if (mode === 'code') {
                this.switchToCode();
            }
        };
        /**
         * Switch from code mode to visual mode
         */
        this.switchToVisualMode = () => {
            // Validate JSON before switching
            try {
                const parsed = parseResponseFormat(this.codeValue);
                // Check if it's supported in visual mode
                const support = validateResponseFormatOnly(parsed, this.limetypes, this.limetype, this.visualModeEnabled);
                if (!support.visualModeSupported) {
                    // Don't switch if visual mode can't render this response format
                    return;
                }
                // Update internal state from parsed value
                this.internalValue = parsed;
                this.mode = 'visual';
                this.change.emit(parsed);
            }
            catch (_a) {
                // Don't switch if JSON is invalid (linter will show the error)
            }
        };
        /**
         * Switch from visual mode to code mode
         */
        this.switchToCode = () => {
            this.updateCodeValue();
            this.mode = 'code';
        };
        /**
         * Handle code editor changes
         * @param event
         */
        this.handleCodeChange = (event) => {
            event.stopPropagation();
            this.codeValue = event.detail;
            // Try to parse and emit if valid
            try {
                const parsed = parseResponseFormat(this.codeValue);
                this.internalValue = parsed;
                this.change.emit(parsed);
            }
            catch (_a) {
                // Invalid JSON - don't emit change
                // Validation errors will be shown by checkVisualModeSupport()
            }
        };
        /**
         * Handle visual mode changes
         * @param event
         */
        this.handleVisualModeChange = (event) => {
            event.stopPropagation();
            this.internalValue = event.detail;
            this.updateCodeValue();
            this.change.emit(event.detail);
        };
    }
    /**
     * Check if visual mode is enabled via feature flag
     */
    get visualModeEnabled() {
        var _a, _b, _c;
        return ((_c = (_b = (_a = this.platform) === null || _a === void 0 ? void 0 : _a.isFeatureEnabled) === null || _b === void 0 ? void 0 : _b.call(_a, 'useLimeQueryBuilderGuiMode')) !== null && _c !== void 0 ? _c : false);
    }
    componentWillLoad() {
        // Initialize internal value
        this.internalValue = this.value || getDefaultResponseFormat();
        // Update code value from internal value
        this.updateCodeValue();
        // Force code mode if visual mode is disabled
        if (!this.visualModeEnabled) {
            this.mode = 'code';
            return;
        }
        // Check if visual mode is supported for current value
        const support = this.checkVisualModeSupport();
        if (!support.visualModeSupported) {
            this.mode = 'code';
        }
    }
    componentWillUpdate() {
        // Sync internal value when prop changes externally
        if (this.value && this.mode === 'visual') {
            this.internalValue = this.value;
        }
    }
    render() {
        const visualModeSupported = this.checkVisualModeSupport();
        return (h("div", { key: '65a41f46fe1088f0d52be0337c427177a1aa1a44', class: "response-format-builder" }, this.label && h("h1", { key: '5a75e321aee3ff6753baccbd72d17c5377f28d28', class: "builder-label" }, this.label), this.helperText && (h("p", { key: 'e13518253b52ff8f847575b4465dc2295c7452f0', class: "builder-helper-text" }, this.helperText)), this.visualModeEnabled && (h("div", { key: '2122357f51fd2185d1b544381eb2199de5b1f56c', class: "mode-controls" }, this.renderModeSwitch(visualModeSupported))), !this.visualModeEnabled || this.mode === 'code' ? (h("div", { class: "code-mode" }, this.renderCodeEditor(visualModeSupported))) : (h("div", { class: "visual-mode" }, this.renderVisualMode()))));
    }
    renderModeSwitch(support) {
        const visualDisabled = !support.visualModeSupported;
        const buttons = [
            {
                id: 'visual',
                title: 'Visual',
            },
            {
                id: 'code',
                title: 'Code',
            },
        ].map((button) => (Object.assign(Object.assign({}, button), { selected: button.id === this.mode })));
        return (h("limel-button-group", { value: buttons, disabled: visualDisabled, onChange: this.handleModeChange }));
    }
    renderCodeEditor(support) {
        return (h("div", { class: "code-editor-container" }, h("limel-code-editor", { value: this.codeValue, language: "json", lineNumbers: true, fold: true, lint: true, onChange: this.handleCodeChange }), !support.valid && support.validationErrors.length > 0 && (h("div", { class: "validation-errors" }, h("strong", null, "Invalid Response Format:"), h("ul", null, support.validationErrors.map((error) => (h("li", null, error)))))), this.visualModeEnabled &&
            support.valid &&
            !support.visualModeSupported &&
            support.visualModeLimitations.length > 0 && (h("div", { class: "visual-mode-limitations" }, h("strong", null, "Cannot switch to visual mode:"), h("ul", null, support.visualModeLimitations.map((limitation) => (h("li", null, limitation))))))));
    }
    renderVisualMode() {
        return (h("limebb-lime-query-response-format-editor", { platform: this.platform, context: this.context, limetype: this.limetype, value: this.internalValue, onChange: this.handleVisualModeChange }));
    }
    /**
     * Check if current value can be rendered in visual mode
     */
    checkVisualModeSupport() {
        if (!this.limetypes) {
            return {
                valid: false,
                visualModeSupported: false,
                validationErrors: ['Limetypes not loaded'],
                visualModeLimitations: [],
            };
        }
        // Try to parse code value if in code mode
        let valueToCheck;
        if (this.mode === 'code') {
            try {
                valueToCheck = parseResponseFormat(this.codeValue);
            }
            catch (error) {
                return {
                    valid: false,
                    visualModeSupported: false,
                    validationErrors: [error.message],
                    visualModeLimitations: [],
                };
            }
        }
        else {
            valueToCheck = this.internalValue;
        }
        return validateResponseFormatOnly(valueToCheck, this.limetypes, this.limetype, this.visualModeEnabled);
    }
    /**
     * Update code value from internal state
     */
    updateCodeValue() {
        this.codeValue = stringifyResponseFormat(this.internalValue);
    }
};
__decorate([
    Le()
], LimeQueryResponseFormatBuilder.prototype, "limetypes", void 0);
LimeQueryResponseFormatBuilder.style = limeQueryResponseFormatBuilderCss();

export { LimeQueryResponseFormatBuilder as limebb_lime_query_response_format_builder };
