/*!
 * KoliBri - The accessible HTML-Standard
 */
import { setState, validateReadOnly, validateRequired, validateSuggestions, watchValidator } from "../../schema";
import { validateAutoComplete } from "../../schema/props/auto-complete";
import { validateTypeInputDate } from "../../schema/props/type-input-date";
import { InputIconController } from "../@deprecated/input/controller-icon";
export class InputDateController extends InputIconController {
    constructor(component, name, host) {
        super(component, name, host);
        this.validateIso8601 = (propName, value, afterPatch) => {
            return watchValidator(this.component, propName, (value) => value === undefined || value === null || value === '' || this.validateDateString(value), new Set(['Date', 'string{ISO-8601}']), InputDateController.tryParseToString(value, this.component._type, this.component._step), {
                hooks: {
                    afterPatch: (value) => {
                        if (typeof value === 'string' && afterPatch) {
                            afterPatch(value);
                        }
                    },
                },
            });
        };
        this.component = component;
    }
    validateAutoComplete(value) {
        validateAutoComplete(this.component, value);
    }
    validateSuggestions(value) {
        validateSuggestions(this.component, value);
    }
    static tryParseToString(value, type, step) {
        if (typeof value === 'string' || value === null) {
            return value;
        }
        if (typeof value === 'object' && value instanceof Date) {
            const formattedYear = value.getFullYear();
            const formattedMonth = String(value.getMonth() + 1).padStart(2, '0');
            const formattedDay = String(value.getDate()).padStart(2, '0');
            const formattedHours = String(value.getHours()).padStart(2, '0');
            const formattedMinutes = String(value.getMinutes()).padStart(2, '0');
            const formattedSeconds = String(value.getSeconds()).padStart(2, '0');
            const formattedDate = [formattedYear, formattedMonth, formattedDay].join('-');
            const formattedTimeWithSeconds = [formattedHours, formattedMinutes, formattedSeconds].join(':');
            switch (type) {
                case 'date':
                    return formattedDate;
                case 'datetime-local':
                    return `${formattedDate}T${formattedTimeWithSeconds}`;
                case 'month':
                    return `${formattedYear}-${formattedMonth}`;
                case 'time':
                    if (step === undefined || String(step) === '60') {
                        return `${formattedHours}:${formattedMinutes}`;
                    }
                    else {
                        return formattedTimeWithSeconds;
                    }
                case 'week':
                    return `${formattedYear}-W${this.getWeekNumberOfDate(value)}`;
            }
        }
    }
    static getWeekNumberOfDate(date) {
        const copiedDate = new Date(date);
        const nDay = (copiedDate.getDay() + 6) % 7;
        copiedDate.setDate(copiedDate.getDate() - nDay + 3);
        const n1stThursday = copiedDate.valueOf();
        copiedDate.setMonth(0, 1);
        if (copiedDate.getDay() !== 4) {
            copiedDate.setMonth(0, 1 + ((4 - copiedDate.getDay() + 7) % 7));
        }
        const dayOfYear = 1 + Math.ceil((n1stThursday - copiedDate.valueOf()) / 604800000);
        return dayOfYear.toString().padStart(2, '0');
    }
    validateDateString(value) {
        switch (this.component._type) {
            case 'date':
                return InputDateController.isoDateRegex.test(value);
            case 'datetime-local':
                return InputDateController.isoLocalDateTimeRegex.test(value);
            case 'month':
                return InputDateController.isoMonthRegex.test(value);
            case 'time':
                return InputDateController.isoTimeRegex.test(value);
            case 'week':
                return InputDateController.isoWeekRegex.test(value);
            default:
                return false;
        }
    }
    onBlur(event) {
        super.onBlur(event);
        if (!!event.target.value !== !!this.component._value) {
            this.component._value = event.target.value;
        }
    }
    validateMax(value) {
        this.validateIso8601('_max', value);
    }
    validateMin(value) {
        this.validateIso8601('_min', value);
    }
    validateOn(value) {
        setState(this.component, '_on', Object.assign(Object.assign({}, value), { onChange: (e, v) => {
                if (!!v !== !!this.component._value) {
                    this.component._value = v;
                }
                if (value === null || value === void 0 ? void 0 : value.onChange) {
                    value.onChange(e, v);
                }
            } }));
    }
    validateReadOnly(value) {
        validateReadOnly(this.component, value);
    }
    validateRequired(value) {
        validateRequired(this.component, value);
    }
    validateStep(value) {
        this.validateNumber('_step', value);
    }
    validateType(value) {
        validateTypeInputDate(this.component, value);
    }
    validateValue(value) {
        this.validateValueEx(value);
    }
    validateValueEx(value, afterPatch) {
        this.validateIso8601('_value', value, afterPatch);
        this.setFormAssociatedValue(this.component.state._value);
    }
    componentWillLoad() {
        super.componentWillLoad();
        this.validateAutoComplete(this.component._autoComplete);
        this.validateMax(this.component._max);
        this.validateMin(this.component._min);
        this.validateLabel(this.component._label);
        this.validateSuggestions(this.component._suggestions);
        this.validateOn(this.component._on);
        this.validateReadOnly(this.component._readOnly);
        this.validateRequired(this.component._required);
        this.validateStep(this.component._step);
        this.validateType(this.component._type);
        this.validateValue(this.component._value);
    }
}
InputDateController.isoDateRegex = /^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])/;
InputDateController.isoLocalDateTimeRegex = /^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])[T ][0-2]\d:[0-5]\d(:[0-5]\d(?:\.\d+)?)?/;
InputDateController.isoMonthRegex = /^\d{4}-([0]\d|1[0-2])/;
InputDateController.isoTimeRegex = /^[0-2]\d:[0-5]\d(:[0-5]\d(?:\.\d+)?)?/;
InputDateController.isoWeekRegex = /^\d{4}-W(?:[0-4]\d|5[0-3])$/;
//# sourceMappingURL=controller.js.map
