<template>
    <view class="hy-checkbox--group" :class="bemClass">
        <template v-for="(item, i) in columns_1" :key="i">
            <view
                class="hy-checkbox cursor-pointer"
                @tap.stop="wrapperClickHandler($event, item)"
                :style="checkboxStyle"
                :class="[
                    `hy-checkbox--label__${iconPlacement}`,
                    borderBottom && placement === 'column' && 'hy-border__bottom'
                ]"
            >
                <view
                    @tap.stop="iconClickHandler($event, item)"
                    :class="iconClasses(item)"
                    :style="iconWrapStyle(item)"
                >
                    <template v-if="item[fieldNames.checked]">
                        <slot
                            v-if="$slots.icon"
                            name="icon"
                            :iconColor="iconColor"
                            :iconSize="addUnit(iconSize)"
                        >
                        </slot>
                        <HyIcon
                            v-else
                            class="hy-checkbox--icon-wrap__icon"
                            :name="IconConfig.CHECK_MASK"
                            :size="addUnit(sizeType[size] || iconSize)"
                            :color="iconColor || '#ffffff'"
                        />
                    </template>
                </view>
                <view
                    :class="[
                        'hy-checkbox--label__wrap',
                        'cursor-pointer',
                        disabled && 'hy-checkbox--label__wrap--disabled'
                    ]"
                    @tap.stop="labelClickHandler($event, item)"
                >
                    <slot name="label" :record="item">
                        <text
                            :style="{
                                color: labelColor,
                                fontSize: addUnit(sizeType[size] || labelSize)
                            }"
                        >
                            {{ item[fieldNames.label] }}
                        </text>
                    </slot>
                </view>
            </view>
        </template>
    </view>
</template>

<script lang="ts">
export default {
    name: 'hy-checkbox',
    options: {
        addGlobalClass: true,
        virtualHost: true,
        styleIsolation: 'shared'
    }
}
</script>

<script setup lang="ts">
import { computed, watch, ref, reactive } from 'vue'
import type { CSSProperties } from 'vue'
import { IconConfig, addUnit, bem, error } from '../../libs'
import type { ICheckBoxEmits } from './typing'
import type { CheckboxColumnsVo } from '../hy-check-button/typing'
import checkboxProps from './props'
// 组件
import HyIcon from '../hy-icon/hy-icon.vue'

/**
 * 复选框组件一般用于需要多个选择的场景，该组件功能完整，使用方便
 * @displayName hy-checkbox
 */
defineOptions({})

const props = defineProps(checkboxProps)
const emit = defineEmits<ICheckBoxEmits>()

const columns_1 = ref()
const sizeType: AnyObject = reactive({
    small: 14,
    medium: 18,
    large: 24
})

watch(
    () => props.modelValue,
    (newValue) => {
        // 判断数组长度为1可以传true/false
        if (props.columns?.length === 1 && typeof newValue === 'boolean') {
            props.columns[0][props.fieldNames.checked] = newValue
            columns_1.value = props.columns
        } else if (Array.isArray(newValue)) {
            columns_1.value = props.columns.map((item) => {
                item[props.fieldNames.checked] = newValue.includes(
                    item[props.fieldNames.value] as string
                )
                return item
            })
        } else {
            error('传入值不是数组，请传数组值')
        }
    },
    { immediate: true }
)

const isDisabled = (disabledVal?: boolean): boolean => props.disabled || !!disabledVal

const checkboxStyle = computed(() => {
    const style: CSSProperties = {}
    if (props.borderBottom && props.placement === 'row') {
        error(
            '检测到您将borderBottom设置为true，需要同时将u-checkbox-group的placement设置为column才有效'
        )
    }
    // 当父组件设置了显示下边框并且排列形式为纵向时，给内容和边框之间加上一定间隔
    if (props.borderBottom && props.placement === 'column') {
        style.paddingBottom = '8px'
    }
    return Object.assign(style, props.customStyle)
})
const bemClass = computed(() => {
    return bem('checkbox-group', props, ['placement'])
})

/**
 * @description 定义icon的Class类名
 * */
const iconClasses = computed(() => {
    return (temp: CheckboxColumnsVo): string[] => {
        let classes: string[] = ['hy-checkbox--icon-wrap', 'cursor-pointer']
        // 组件的形状
        classes.push('hy-checkbox--icon-wrap--' + props.shape)
        if (isDisabled(temp?.disabled)) {
            classes.push('hy-checkbox--icon-wrap--disabled')
        }
        if (temp[props.fieldNames.checked]) {
            classes.push('hy-checkbox--icon-wrap--checked')
            if (isDisabled(temp?.disabled)) {
                classes.push('hy-checkbox--icon-wrap--disabled--checked')
            }
        }
        return classes
    }
})

/**
 * @description 定义icon的样式
 * */
const iconWrapStyle = computed(() => {
    return (temp: CheckboxColumnsVo): CSSProperties => {
        // checkbox的整体样式
        const style: CSSProperties = {}
        style.backgroundColor =
            temp[props.fieldNames.checked] && !isDisabled(temp?.disabled) ? props.activeColor : ''
        style.borderColor =
            temp[props.fieldNames.checked] && !isDisabled(temp?.disabled)
                ? props.activeColor
                : props.inactiveColor
        style.width = addUnit(sizeType[props.size] || props.size)
        style.height = addUnit(sizeType[props.size] || props.size)
        return style
    }
})

/**
 * @description 点击图标
 * */
const iconClickHandler = (e: Event, temp: CheckboxColumnsVo) => {
    e.stopPropagation()
    if (!isDisabled(temp?.disabled)) {
        setRadioCheckedStatus(temp)
    }
}
/**
 * @description 点击整行
 * */
const wrapperClickHandler = (e: Event, temp: CheckboxColumnsVo) => {
    e.stopPropagation()
    if (props.labelDisabled || isDisabled(temp?.disabled)) return
    setRadioCheckedStatus(temp)
}
/**
 * @description 点击label
 * */
const labelClickHandler = (e: Event, temp: CheckboxColumnsVo) => {
    e.stopPropagation()
    if (props.labelDisabled || isDisabled(temp?.disabled)) return
    setRadioCheckedStatus(temp)
}

/**
 * @description 执行函数改变状态传给父值
 * */
const setRadioCheckedStatus = (temp: CheckboxColumnsVo) => {
    // 将本组件标记为与原来相反的状态
    columns_1.value = columns_1.value.map((item: CheckboxColumnsVo) => {
        if (temp[props.fieldNames.value] === item[props.fieldNames.value]) {
            item[props.fieldNames.checked] = !item[props.fieldNames.checked]
        }
        return item
    })
    emit(
        'update:modelValue',
        columns_1.value.length === 1
            ? columns_1.value[0].checked
            : columns_1.value
                  .filter((item: CheckboxColumnsVo) => item[props.fieldNames.checked])
                  .map((item: CheckboxColumnsVo) => item[props.fieldNames.value])
    )
    emit('change', temp)
}
</script>

<style lang="scss" scoped>
@import './index.scss';
</style>
