/*!
 * KoliBri - The accessible HTML-Standard
 */
'use strict';

var common = require('./common-DAAt5YQ7.js');
var bootstrap = require('./bootstrap-De2npoa_.js');

const validateName = (component, value, options) => {
    common.watchString(component, '_name', value, options);
};

const isAssociatedTagName = (name) => name === 'KOL-BUTTON' ||
    name === 'KOL-COMBOBOX' ||
    name === 'KOL-INPUT-CHECKBOX' ||
    name === 'KOL-INPUT-COLOR' ||
    name === 'KOL-INPUT-DATE' ||
    name === 'KOL-INPUT-EMAIL' ||
    name === 'KOL-INPUT-FILE' ||
    name === 'KOL-INPUT-NUMBER' ||
    name === 'KOL-INPUT-PASSWORD' ||
    name === 'KOL-INPUT-RADIO' ||
    name === 'KOL-INPUT-RANGE' ||
    name === 'KOL-INPUT-TEXT' ||
    name === 'KOL-SELECT' ||
    name === 'KOL-SINGLE-SELECT' ||
    name === 'KOL-TEXTAREA';
class AssociatedInputController {
    constructor(component, type, host) {
        var _a, _b, _c, _d;
        this.experimentalMode = common.getExperimentalMode();
        this.setFormAssociatedValue = (rawValue) => {
            var _a;
            const name = (_a = this.formAssociated) === null || _a === void 0 ? void 0 : _a.getAttribute('name');
            if (name === null || name === '') {
                common.devHint(` The form field (${this.type}) must have a name attribute to be form-associated. Please define the _name attribute.`);
            }
            const strValue = this.tryToStringifyValue(rawValue);
            this.syncValue(rawValue, strValue, this.formAssociated);
            this.syncValue(rawValue, strValue, this.syncToOwnInput);
        };
        this.component = component;
        this.host = this.findHostWithShadowRoot(host);
        this.type = type;
        if (((_a = bootstrap.getOptions()) === null || _a === void 0 ? void 0 : _a.reflectInputValues) && isAssociatedTagName((_b = this.host) === null || _b === void 0 ? void 0 : _b.tagName) && component._name) {
            (_c = this.host) === null || _c === void 0 ? void 0 : _c.querySelectorAll('input,select,textarea').forEach((el) => {
                var _a;
                (_a = this.host) === null || _a === void 0 ? void 0 : _a.removeChild(el);
            });
            switch (this.type) {
                case 'button':
                case 'color':
                case 'date':
                case 'email':
                case 'file':
                case 'number':
                case 'password':
                case 'radio':
                case 'range':
                case 'text':
                    this.formAssociated = document.createElement('input');
                    this.formAssociated.setAttribute('type', this.type);
                    break;
                case 'select':
                    this.formAssociated = document.createElement('select');
                    this.formAssociated.setAttribute('multiple', '');
                    break;
                case 'textarea':
                    this.formAssociated = document.createElement('textarea');
                    break;
                case 'checkbox':
                case 'single-select':
                case 'combobox':
                default:
                    this.formAssociated = document.createElement('input');
                    this.formAssociated.setAttribute('type', 'hidden');
            }
            this.formAssociated.setAttribute('data-form-associated', '');
            this.formAssociated.setAttribute('hidden', '');
            (_d = this.host) === null || _d === void 0 ? void 0 : _d.appendChild(this.formAssociated);
        }
    }
    findHostWithShadowRoot(host) {
        while ((host === null || host === void 0 ? void 0 : host.shadowRoot) === null && host !== document.body) {
            const parent = host === null || host === void 0 ? void 0 : host.parentNode;
            if (parent instanceof ShadowRoot) {
                host = parent.host;
            }
            else {
                host = parent instanceof Element ? parent : undefined;
            }
        }
        return host;
    }
    setAttribute(qualifiedName, element, value) {
        if (this.experimentalMode) {
            try {
                value = typeof value === 'object' && value !== null ? JSON.stringify(value) : value;
                if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') {
                    element === null || element === void 0 ? void 0 : element.setAttribute(qualifiedName, `${value}`);
                }
                else {
                    throw new Error(`Invalid value type: ${typeof value}`);
                }
            }
            catch (_a) {
                element === null || element === void 0 ? void 0 : element.removeAttribute(qualifiedName);
            }
        }
    }
    tryToStringifyValue(value) {
        try {
            return typeof value === 'object' && value !== null ? JSON.stringify(value).toString() : value === null || value === undefined ? null : value.toString();
        }
        catch (e) {
            common.devWarning(`The form field raw value is not able to stringify! ${e}`);
            return '';
        }
    }
    syncValue(rawValue, strValue, associatedElement) {
        if (associatedElement) {
            switch (this.type) {
                case 'file':
                    associatedElement.files = rawValue;
                    break;
                case 'select':
                    associatedElement.querySelectorAll('option').forEach((el) => {
                        associatedElement.removeChild(el);
                    });
                    if (Array.isArray(rawValue)) {
                        rawValue.forEach((rawValueItem) => {
                            const strValueItem = this.tryToStringifyValue(rawValueItem);
                            if (typeof strValueItem === 'string') {
                                const option = document.createElement('option');
                                option.setAttribute('value', strValueItem);
                                option.setAttribute('selected', '');
                                associatedElement.appendChild(option);
                            }
                        });
                    }
                    break;
                case 'radio':
                    if (typeof strValue === 'string') {
                        associatedElement.setAttribute('value', strValue);
                        associatedElement.setAttribute('checked', '');
                        associatedElement.value = strValue;
                    }
                    break;
                default:
                    if (typeof strValue === 'string') {
                        associatedElement.setAttribute('value', strValue);
                        associatedElement.value = strValue;
                    }
                    else {
                        associatedElement.removeAttribute('value');
                        associatedElement.value = '';
                    }
            }
        }
    }
    validateName(value) {
        validateName(this.component, value, {
            hooks: {
                afterPatch: () => {
                    this.setAttribute('name', this.formAssociated, this.component.state._name);
                },
            },
        });
        if (typeof value === 'undefined') {
            common.devHint(`A name on input fields or switches is not strictly required, but it might be relevant for the autocomplete function and for the static submission of the input field.`);
        }
    }
    validateSyncValueBySelector(value) {
        if (this.experimentalMode && typeof value === 'string') {
            const input = document.querySelector(value);
            if (input) {
                this.syncToOwnInput = input;
            }
        }
    }
    componentWillLoad() {
        this.validateName(this.component._name);
        this.validateSyncValueBySelector(this.component._syncValueBySelector);
    }
}

exports.AssociatedInputController = AssociatedInputController;
//# sourceMappingURL=associated.controller-CUvZCmFF.js.map

//# sourceMappingURL=associated.controller-CUvZCmFF.js.map