<template>
<div class="widget-list">
    <ul>
        <li v-for="(item, index) in ListResultField"
            v-show="!(row.hideKeys || []).includes(item.label)"
            :key="index"
        >
            <block>{{ item[row.key] || item.label }}</block>
            <span>
                <EditPen
                    v-click-outside="onClickOutside"
                    @click="clickItem( $event, index)"
                />
                <Delete @click="delColumnItem(index)" />
            </span>
        </li>
        <li style="justify-content: center; cursor: pointer">
            <el-button @click="addColumnItem">添加</el-button>
        </li>
    </ul>
    <el-popover
        ref="popoverRef"
        placement="left"
        title="修改数据"
        trigger="click"
        :width="500"
        :visible="visible"
        :virtual-ref="buttonRef"
        virtual-triggering
        @before-leave="beforeLeave"
    >
        <div style="text-align: right; margin: 0">
            <info-form
                ref="formRef"
                :key="KU"
                :config="config"
                :modelData="modelDataRow"
            />
        </div>
    </el-popover>
</div>

</template>

<script setup>
import {FormConfig} from '../formConfig'
import infoForm from '../../infoForm/infoForm.vue'
import {globalFormValue, deepCopy} from '../../../script/index'
import {EditPen, Delete} from '@element-plus/icons-vue'
import {ref, unref, reactive, computed} from 'vue'
import { ClickOutside as vClickOutside } from 'element-plus'
let props = defineProps({
    row: {
        type: Object,
        default: () => {
        }
    },
    modelData: {
        type: Object,
        default: () => {
        }
    }
})

const convertObjectToArray = (obj) => {
    return Object.keys(obj).map(key => {
        return {
            label: key,
            value: obj[key]
        }
    })
}

const convertArrayToObject = (arr) => {
    return arr.reduce((acc, item) => {
        acc[item.label] = item.value
        return acc
    }, {})
}

let ListResultField = ref(globalFormValue(props.modelData, props.row.model)._get()) // 获取当前所有数据
if (props.row.pattern === 'Object') {
    ListResultField.value = convertObjectToArray(ListResultField.value)
}

const visible = ref(false)
const isEdit = ref(false)
let buttonRef = ref()
const popoverRef = ref()
let modelDataRow = reactive({})
let formRef = ref()
let index = ref(0)
let KU = ref(0)
const refresh = () => {
    KU.value++
    // console.log(`%c ${KU.value}`, 'color:purple;font-size:18px;font-family:system-ui;')
}

const setRule = (rules, init) => {
    removeRule()
    config.rule.splice(-1, 0, ...rules)
    !init && refresh()
}

// 不在row.rule中的都移除
const removeRule = () => {
    const len = getRule.value.length
    // 新加的个数
    const addCount = config.rule.length - len - 1 // eg: 5-2-1
    addCount > 0 && config.rule.splice(len, addCount)
}

const getRule = computed(() => {
    return typeof props.row.rule === 'function' ? props.row.rule(modelDataRow, setRule) : props.row.rule
})
let config = new FormConfig({
    ref: 'formRef',
    size: 'small',
    labelWidth: '120px',
    labelPosition: 'right',
    rule: [...getRule.value, {
        label: '',
        model: '',
        type: 'infoButton',
        operation: [
            {
                show: () => true,
                label: '保存',
                type: 'primary',
                methods: () => {
                    formRef.value.validate((valid) => {
                        if (valid) {
                            if (isEdit.value) {
                                ListResultField.value[index.value] = JSON.parse(JSON.stringify(modelDataRow))
                            } else {
                                ListResultField.value.push(JSON.parse(JSON.stringify(modelDataRow)))
                            }
                            if (props.row.pattern === 'Object') {
                                const value = convertArrayToObject(ListResultField.value)
                                globalFormValue(props.modelData, props.row.model)._set(value)
                            } else {
                                globalFormValue(props.modelData, props.row.model)._set(ListResultField.value)
                            }
                            visible.value = false
                        }
                    })
                }
            }
        ]
    }]
})

// popover隐藏前
const beforeLeave = () => {
    removeRule()
    refresh()
}

// 编辑
const clickItem = (e, i) => {
    index.value = i
    isEdit.value = true
    visible.value = true
    buttonRef.value = e.target
    Object.assign(modelDataRow, deepCopy(ListResultField.value[i]))
    if (props.row.editBind) { // 编辑回调
        const rule = getRule.value.filter(item => item.model === props.row.editBind)[0]
        rule.methods(modelDataRow[props.row.editBind])
    }
}
const onClickOutside = (e) => {
    if (visible.value && !unref(popoverRef).popperRef.contentRef.contains(e.target)) {
        visible.value = false
    }
} // TODO 事件解绑

// 添加
const addColumnItem = (e) => {
    visible.value = true
    isEdit.value = false
    buttonRef.value = e.target
    Object.assign(modelDataRow, getDefaultByRule(getRule.value))
}

// 根据 rule 获取默认值
const getDefaultByRule = (ruleArray) => {
    return ruleArray.reduce((acc, item) => {
        let keyList = item.deepData === 0 ? [item.model] : item.model.split('.')
        if (keyList.length === 1) {
            acc[keyList[0]] = item.defaultVal
        } else if (keyList.length === 2) {
            if (acc[keyList[0]]) {
                acc[keyList[0]][keyList[1]] = item.defaultVal
            } else {
                acc[keyList[0]] = {
                    [keyList[1]]: item.defaultVal
                }
            }
        }
        // acc[item.model] = item.defaultVal
        return acc
    }, {})
}
Object.assign(modelDataRow, getDefaultByRule(getRule.value))

const delColumnItem = (i) => {
    ListResultField.value.splice(i, 1)
}
</script>
<style scoped lang="scss">
.widget-list {
    width: 100%;
    height: 100%;
    > ul {
        padding: 0;
    }
}
.widget-list ul > li{
    margin: 10px 0;
    padding: 0 10px;
    border: 1px solid var(--info-color-f3f3f3);
    display: flex;
    justify-content: space-between;
    height: 30px;
    line-height: 30px;
    svg{
        display: inline-block;
        width: 16px;
        margin: 0 5px;
        cursor: pointer;
    }
}
.warp{
    padding: 0;
}
</style>
