"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const vooks_1 = require("vooks");
const seemly_1 = require("seemly");
const _mixins_1 = require("../../_mixins");
const _internal_1 = require("../../_internal");
const _utils_1 = require("../../_utils");
const styles_1 = require("../styles");
const CheckMark_1 = require("./CheckMark");
const LineMark_1 = require("./LineMark");
const CheckboxGroup_1 = require("./CheckboxGroup");
const index_cssr_1 = require("./styles/index.cssr");
const checkboxProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { size: String, checked: {
        type: [Boolean, String, Number],
        default: undefined
    }, defaultChecked: {
        type: [Boolean, String, Number],
        default: false
    }, value: [String, Number], disabled: {
        type: Boolean,
        default: undefined
    }, indeterminate: Boolean, label: String, focusable: {
        type: Boolean,
        default: true
    }, checkedValue: {
        type: [Boolean, String, Number],
        default: true
    }, uncheckedValue: {
        type: [Boolean, String, Number],
        default: false
    }, 'onUpdate:checked': [Function, Array], onUpdateChecked: [Function, Array], 
    // private
    privateTableHeader: Boolean, 
    // deprecated
    onChange: [Function, Array] });
exports.default = (0, vue_1.defineComponent)({
    name: 'Checkbox',
    props: checkboxProps,
    setup(props) {
        if (process.env.NODE_ENV !== 'production') {
            (0, vue_1.watchEffect)(() => {
                if (props.onChange) {
                    (0, _utils_1.warnOnce)('checkbox', '`on-change` is deprecated, please use `on-update:checked` instead.');
                }
            });
        }
        const { mergedClsPrefixRef } = (0, _mixins_1.useConfig)(props);
        const formItem = (0, _mixins_1.useFormItem)(props, {
            mergedSize(NFormItem) {
                const { size } = props;
                if (size !== undefined)
                    return size;
                if (NCheckboxGroup) {
                    const { value: mergedSize } = NCheckboxGroup.mergedSizeRef;
                    if (mergedSize !== undefined) {
                        return mergedSize;
                    }
                }
                if (NFormItem) {
                    const { mergedSize } = NFormItem;
                    if (mergedSize !== undefined)
                        return mergedSize.value;
                }
                return 'medium';
            },
            mergedDisabled(NFormItem) {
                const { disabled } = props;
                if (disabled !== undefined)
                    return disabled;
                if (NCheckboxGroup) {
                    if (NCheckboxGroup.disabledRef.value)
                        return true;
                    const { maxRef: { value: max }, checkedCountRef } = NCheckboxGroup;
                    if (max !== undefined &&
                        checkedCountRef.value >= max &&
                        !renderedCheckedRef.value) {
                        return true;
                    }
                    const { minRef: { value: min } } = NCheckboxGroup;
                    if (min !== undefined &&
                        checkedCountRef.value <= min &&
                        renderedCheckedRef.value) {
                        return true;
                    }
                }
                if (NFormItem) {
                    return NFormItem.disabled.value;
                }
                return false;
            }
        });
        const { mergedDisabledRef, mergedSizeRef } = formItem;
        const NCheckboxGroup = (0, vue_1.inject)(CheckboxGroup_1.checkboxGroupInjectionKey, null);
        const uncontrolledCheckedRef = (0, vue_1.ref)(props.defaultChecked);
        const controlledCheckedRef = (0, vue_1.toRef)(props, 'checked');
        const mergedCheckedRef = (0, vooks_1.useMergedState)(controlledCheckedRef, uncontrolledCheckedRef);
        const renderedCheckedRef = (0, vooks_1.useMemo)(() => {
            if (NCheckboxGroup) {
                const groupValueSet = NCheckboxGroup.valueSetRef.value;
                if (groupValueSet && props.value !== undefined) {
                    return groupValueSet.has(props.value);
                }
                return false;
            }
            else {
                return mergedCheckedRef.value === props.checkedValue;
            }
        });
        const themeRef = (0, _mixins_1.useTheme)('Checkbox', 'Checkbox', index_cssr_1.default, styles_1.checkboxLight, props, mergedClsPrefixRef);
        function toggle(e) {
            if (NCheckboxGroup && props.value !== undefined) {
                NCheckboxGroup.toggleCheckbox(!renderedCheckedRef.value, props.value);
            }
            else {
                const { onChange, 'onUpdate:checked': _onUpdateCheck, onUpdateChecked } = props;
                const { nTriggerFormInput, nTriggerFormChange } = formItem;
                const nextChecked = renderedCheckedRef.value
                    ? props.uncheckedValue
                    : props.checkedValue;
                if (_onUpdateCheck) {
                    (0, _utils_1.call)(_onUpdateCheck, nextChecked, e);
                }
                if (onUpdateChecked) {
                    (0, _utils_1.call)(onUpdateChecked, nextChecked, e);
                }
                if (onChange)
                    (0, _utils_1.call)(onChange, nextChecked, e); // deprecated
                nTriggerFormInput();
                nTriggerFormChange();
                uncontrolledCheckedRef.value = nextChecked;
            }
        }
        function handleClick(e) {
            if (!mergedDisabledRef.value) {
                toggle(e);
            }
        }
        function handleKeyUp(e) {
            if (mergedDisabledRef.value)
                return;
            switch (e.code) {
                case 'Space':
                case 'Enter':
                case 'NumpadEnter':
                    toggle(e);
            }
        }
        function handleKeyDown(e) {
            switch (e.code) {
                case 'Space':
                    e.preventDefault();
            }
        }
        return Object.assign(formItem, {
            mergedClsPrefix: mergedClsPrefixRef,
            mergedDisabled: mergedDisabledRef,
            renderedChecked: renderedCheckedRef,
            mergedTheme: themeRef,
            labelId: (0, seemly_1.createId)(),
            handleClick,
            handleKeyUp,
            handleKeyDown,
            cssVars: (0, vue_1.computed)(() => {
                const { value: mergedSize } = mergedSizeRef;
                const { common: { cubicBezierEaseInOut }, self: { borderRadius, color, colorChecked, colorDisabled, colorTableHeader, colorTableHeaderModal, colorTableHeaderPopover, checkMarkColor, checkMarkColorDisabled, border, borderFocus, borderDisabled, borderChecked, boxShadowFocus, textColor, textColorDisabled, checkMarkColorDisabledChecked, colorDisabledChecked, borderDisabledChecked, labelPadding, [(0, _utils_1.createKey)('fontSize', mergedSize)]: fontSize, [(0, _utils_1.createKey)('size', mergedSize)]: size } } = themeRef.value;
                return {
                    '--size': size,
                    '--bezier': cubicBezierEaseInOut,
                    '--border-radius': borderRadius,
                    '--border': border,
                    '--border-checked': borderChecked,
                    '--border-focus': borderFocus,
                    '--border-disabled': borderDisabled,
                    '--border-disabled-checked': borderDisabledChecked,
                    '--box-shadow-focus': boxShadowFocus,
                    '--color': color,
                    '--color-checked': colorChecked,
                    '--color-table-header': colorTableHeader,
                    '--color-table-header-modal': colorTableHeaderModal,
                    '--color-table-header-popover': colorTableHeaderPopover,
                    '--color-disabled': colorDisabled,
                    '--color-disabled-checked': colorDisabledChecked,
                    '--text-color': textColor,
                    '--text-color-disabled': textColorDisabled,
                    '--check-mark-color': checkMarkColor,
                    '--check-mark-color-disabled': checkMarkColorDisabled,
                    '--check-mark-color-disabled-checked': checkMarkColorDisabledChecked,
                    '--font-size': fontSize,
                    '--label-padding': labelPadding
                };
            })
        });
    },
    render() {
        const { $slots, renderedChecked, mergedDisabled, indeterminate, privateTableHeader, cssVars, labelId, label, mergedClsPrefix, focusable, handleKeyUp, handleKeyDown, handleClick } = this;
        return ((0, vue_1.h)("div", { class: [
                `${mergedClsPrefix}-checkbox`,
                renderedChecked && `${mergedClsPrefix}-checkbox--checked`,
                mergedDisabled && `${mergedClsPrefix}-checkbox--disabled`,
                indeterminate && `${mergedClsPrefix}-checkbox--indeterminate`,
                privateTableHeader && `${mergedClsPrefix}-checkbox--table-header`
            ], tabindex: mergedDisabled || !focusable ? undefined : 0, role: "checkbox", "aria-checked": indeterminate ? 'mixed' : renderedChecked, "aria-labelledby": labelId, style: cssVars, onKeyup: handleKeyUp, onKeydown: handleKeyDown, onClick: handleClick, onMousedown: () => {
                const preventDefault = (e) => {
                    e.preventDefault();
                };
                window.addEventListener('selectstart', preventDefault);
                setTimeout(() => {
                    window.removeEventListener('selectstart', preventDefault);
                }, 0);
            } },
            (0, vue_1.h)("div", { class: `${mergedClsPrefix}-checkbox-box` },
                (0, vue_1.h)(_internal_1.NIconSwitchTransition, null, {
                    default: () => this.indeterminate ? ((0, vue_1.h)("div", { key: "indeterminate", class: `${mergedClsPrefix}-checkbox-icon` }, LineMark_1.default)) : ((0, vue_1.h)("div", { key: "check", class: `${mergedClsPrefix}-checkbox-icon` }, CheckMark_1.default))
                }),
                (0, vue_1.h)("div", { class: `${mergedClsPrefix}-checkbox-box__border` })),
            label !== null || $slots.default ? ((0, vue_1.h)("span", { class: `${mergedClsPrefix}-checkbox__label`, id: labelId }, (0, vue_1.renderSlot)($slots, 'default', undefined, () => [label]))) : null));
    }
});
