<template>
    <label
        class="nus_checkbox nus_checktmp"
        :class="[disabled && 'nu_disabled']"
        @click.stop="_onClick($event)"
        @tap.stop="_onTap($event)">
        <input
            :disabled="disabled"
            @input="_onChange"
            v-model="myChecked"
            type="checkbox"
            :value="value"
            @click.stop
            @tap.stop/>
        <div class="nu_check">
            <slot name="hook_lable"
                :disabled="disabled"
                :checked="myChecked"
                :mValue="myValue"
                :value="value">
                <span
                    class="nu_lable nu_lable-pre"
                    v-if="label || isPrefix">
                    <slot
                        name="hook_prefix"
                        :disabled="disabled"
                        :checked="myChecked"
                        :mValue="myValue"
                        :value="value">
                    </slot>
                    {{ label }}
                </span>
                <slot name="hook_icon"
                    :disabled="disabled"
                    :checked="myChecked"
                    :mValue="myValue"
                    :value="value">
                    <span
                        class="nu_check-icon"
                        :class="iconClass"
                        :data-icon="icon"
                        :data-icon-active="iconActive">
                    </span>
                </slot>
                <span
                    class="nu_lable"
                    v-if="isDefalut || isPrefix">
                    <slot
                        :disabled="disabled"
                        :checked="myChecked"
                        :mValue="myValue"
                        :value="value"></slot>
                    <slot
                        name="hook_suffix"
                        :disabled="disabled"
                        :checked="myChecked"
                        :mValue="myValue"
                        :value="value">
                    </slot>
                </span>
            </slot>
        </div>
    </label>
</template>

<script>
import { callFn, diffData } from 'nimble-lib';
import CheckTmp from '../_comm/CheckTmp';
import vModel from '../../../Mixins/vModel';
import attrSync from '../../../Mixins/attrSync';
export default {
    extends: CheckTmp,
    name: 'NuCheckbox',

    props: {
        /**
         * 选中的图标
         */
        iconActive: {
            type: String,
            default: '\ue60e'
        },
        /**
         * 内容文本
         */
        value: {
            // type: String,
            default: true
        }
    },
    data() {
        let _that = this;
        let isArray = _that.mValue instanceof Array;
        if (typeof _that.multiple === 'boolean') {
            isArray = _that.multiple;
        }
        return {
            isArray: isArray
        };
    },
    mixins: [
        vModel({
            mValueChange(nowVal) {
                let _that = this;
                _that.myValue = nowVal;
                _that._setMyCheck();
                return false;
            },
            myValueChange() {
                return false;
            }
        }),
        attrSync('checked', {
            myValueChange() {
                this._setMyValue();
                // return false; // 注掉后.sync时才能获取到值
            }
        })
    ],
    // watch: {
    //     /* 选中 */
    //     myChecked() {
    //         this._setMyValue();
    //     },
    //     /* 传入的数据发生改变 */
    //     mValue (nowVal) {
    //         let _that = this;
    //         _that.myValue = nowVal;
    //         _that._setMyCheck();
    //     }
    // },
    created() {
        let _that = this;
        if (_that.myChecked) {
            _that._setMyValue();
        } else {
            _that._setMyCheck();
        }
    },
    methods: {
        /**
         * 设置myChecked的值
         */
        _setMyCheck() {
            let _that = this;
            let _cValue = _that.value;
            let _mValue = _that.mValue;
            _that.myChecked = _that.isArray ? (_that._hasItem(_mValue, _cValue) > -1) : _that._diffValue(_mValue, _cValue);
        },

        /**
         * 设置myValue的值
         */
        _setMyValue() {
            let _that = this;
            if (_that.isArray) {
                _that._setMyValueList(_setMyValue);
            } else {
                _that._setMyValueObj(_setMyValue);
            }

            /**
             * 设置myValue
             * @param {*} value 需要设置的值
             */
            function _setMyValue(value) {
                if (typeof _that.value === 'boolean' && !value) {
                    value = false;
                }
                _that.myValue = value;
                _that._valueChange();
            }
        },

        /**
         * 设置非列表值
         * @param {Function} cb 回调
         */
        _setMyValueObj(cb) {
            let _that = this;
            let checked = _that.myChecked;
            let _cValue = _that.value;
            let _isSame = _that._diffValue(_that.myValue, _cValue);
            if (checked && !_isSame) {
                callFn(cb, [_cValue]);
            } else if (!checked && _isSame) {
                callFn(cb, [_that.noValue]);
            }
        },
        /**
         * 设置列表值
         * @param {Function} cb 回调
         */
        _setMyValueList(cb) {
            let _that = this;
            let checked = _that.myChecked;
            let _myValue = _that.myValue || [];
            let _cValue = _that.value;
            let key = _that._genItemMapKey(_cValue);
            if (!_myValue.__keyMap) {
                _myValue.__keyMap = {};
                Object.defineProperty(_myValue, '__keyMap', {
                    enumerable: false
                });
            }
            let _index;
            if (key && _myValue.__keyMap[key]) {
                _index = 0;
            } else {
                _index = _that._hasItem(_myValue, _cValue);
            }
            if (checked && _index < 0) {
                _myValue.push(_cValue);
                // if (key) { // 暂时先关掉还有bug（选中的在删除的时候会全部删掉）
                //     _myValue.__keyMap[key] = _cValue;
                // }
                callFn(cb, [_myValue]);
            } else if (!checked && _index > -1) {
                if (key) {
                    if (_myValue.__keyMap[key]) {
                        _index = _that._hasItem(_myValue, _cValue);
                        _myValue.__keyMap[key] = null;
                        delete _myValue.__keyMap[key];
                    }
                }
                _myValue.splice(_index, 1);
                callFn(cb, [_myValue]);
            }
        },
        _genItemMapKey(itemData) {
            let _that = this;
            let diffKey = _that.diffKey;
            let res = [];
            if (diffKey instanceof Array) {
                diffKey.forEach((key) => {
                    res.push(itemData[key]);
                });
            }
            return res.length ? res.join('___') : '';
        },
        /**
         * 设置列表
         * @param {Array} list 当前选中列表
         * @param {*} item 当前项值
         * @return {Number} 返回索引
         */
        _hasItem(list, item) {
            let _that = this;
            let _index = -1;
            if (list instanceof Array) {
                list.every((_item, key) => {
                    if (_that._diffValue(item, _item)) {
                        _index = key;
                        return false;
                    }
                    return true;
                });
            }
            return _index;
        },
        /**
         * 比较两个值是否想等
         * @param {*} myValue 当前选中的值
         * @param {*} value 当前项的值
         * @return {Boolean}
         */
        _diffValue(myValue, value) {
            let _that = this;
            if (typeof _that.value === 'boolean' || _that.value === null || _that.value === undefined) {
                value = _that.value || false;
            }
            return diffData(myValue, value, _that.diffKey);
        }
    }
};
</script>

<style lang="scss">
@import '../../../_assets/style/_iconFont.scss';
@import '../../../_assets/style/_var.scss';
@import '../../../_assets/style/_mixin.scss';

</style>
