<template>
    <section
        id="operationPanel"
        class="operationPanel"
        :class="{'boxshow-style': showBoxShow}"
    >
        <div
            class="operation-main"
            :style="{
                height: height
            }"
        >
            <div
                class="operationLeft"
            >
                <slot name="left" />
            </div>
            <div class="operationRight">
                <slot name="right" />
            </div>
        </div>
        <div
            v-if="paramList.length"
            class="field-group"
        >
            {{ $t('searchConditions') }}:
            <span
                v-for="(item, index) of paramList"
                :key="index"
            >
                <span
                    v-if="index > 0 && paramList[index - 1].text !== '('"
                    :class="{ 'andOr': item.andOr }"
                >{{ item.andOr }}</span>
                <span
                    :class="{ 'text': !['(', ')'].includes(item.text) }"
                >
                    {{ item.text }}
                    <i
                        v-if="!['(', ')'].includes(item.text)"
                        class="el-icon-close delete"
                        @click="removeField(item, index)"
                    />
                </span>
            </span>
            <i
                class="el-icon-delete delete"
                @click="clearFields"
            />
        </div>
    </section>
</template>
<script lang="ts">
import { defineComponent, reactive, watch, onBeforeMount } from 'vue'
import { globalGetDate, deepCopy } from '../../script'
import { conditions } from '../../hooks/option'
interface Param {
    level: number
    text: string
    name?: string
    andOr?: string
    key?: string
}
export default defineComponent({
    name: 'OperationPanel',
    props: {
        height: {
            type: String,
            default: '60px'
        },
        showBoxShow: { // 是否显示阴影
            type: Boolean,
            default: true
        },
        fieldGroup: {
            type: Object,
            default: () => {}
        },
        columns: {
            type: Array,
            default: () => []
        },
        columnI18n: {
            type: Boolean,
            default: true
        }
    },
    setup (props, { emit }) {
        const { columns, columnI18n } = props
        let fieldMap = reactive({})
        let paramList = reactive([] as Param[])

        /* watch */
        watch(() => props.fieldGroup, (nv) => {
                paramList.length = 0
                generateParamList(nv, 1)
            },
            { deep: true }
        )
        onBeforeMount(() => {
            columns.forEach((column:any) => {
                const label = column.label // columnI18n ? column.label : this.$t('' + column.label)
                fieldMap[column.prop] = $t(label)
            })
        })
        /* methods */
        const removeField = (removed, index) => {
            const prev = paramList[index - 1]
            const next = paramList[index + 1]
            if (!prev && next?.text === '(') {
                const end = paramList.findIndex((item:Param) => item.level === next.level && item.text === ')')
                paramList.splice(end, 1) // 从大到小
                paramList.splice(index + 1, 1)
                paramList.splice(index, 1)
            } else if (prev?.text === '(' && next?.text === ')') {
                paramList.splice(index - 1, 3) // 从小到大
            } else {
                paramList.splice(index, 1)
            }
            resetFieldGroup(removed, props.fieldGroup, 1)
            emit('removed', props.fieldGroup, removed.level === 1 ? [removed] : []) // 只关注第一层
        }
        // 删除后的fieldGroup
        const resetFieldGroup = (removed, group, level) => {
            for (let [index, field] of group.fields.entries()) {
                const key = field.key || field.name
                if (removed.key === key) { // 删除这一项
                    if (index === 0 && group.fields[index + 1]) {
                        group.fields[index + 1].andOr = 'AND'
                    }
                    group.fields.splice(index, 1)
                    break
                } else if (field.type === 'FieldGroup') {
                    resetFieldGroup(removed, field, level + 1)
                    if (field.fields.length === 0) { // group下无field 删除
                        group.fields.splice(index, 1)
                        break
                    }
                }
            }
        }
        // 清空
        const clearFields = () => {
            paramList.splice(0)
            const final = deepCopy(props.fieldGroup)
            const fields:[] = props.fieldGroup.fields.filter(field => field.name && !Object.keys(fieldMap).includes(field.name))
            const removed:[] = props.fieldGroup.fields.filter(field => field.name && Object.keys(fieldMap).includes(field.name)) // 只关注第一层
            final.fields = fields
            emit('removed', final, removed)
        }
        // fieldGroup => paramList
        const generateParamList = (group, level) => {
            const trans = { 'AND': '并且', 'OR': '或者' }
            for (let field of group.fields) {
                if (field.type === 'Field') {
                    if (!Object.keys(fieldMap).includes(field.queryFeature?.name || field.name)) continue
                    if (field.queryFeature) {
                        setParamList(field.queryFeature, level)
                    } else {
                        setParamList(field, level)
                    }
                } else if (field.type === 'FieldGroup' && field.fields.length > 0) {
                    if (field.queryFeature) {
                        setParamList(field.queryFeature, level)
                        continue
                    }
                    paramList.push({ level, andOr: trans[field.andOr.toUpperCase()], text: '(' })
                    generateParamList(field, level + 1)
                    paramList.push({ level, text: ')' })
                }
            }
        }
        const setParamList = (field, level) => {
            const trans = { 'AND': '并且', 'OR': '或者' }
            const andOr = trans[field.andOr.toUpperCase()]
            const name = fieldMap[field.name]
            let oper = conditions[field.oper].alias || conditions[field.oper].label
            oper = $t(oper)
            let value = (field.label || field.value).toString()
            if (name.endsWith('时间') && field.oper.endsWith('BETWEEN')) {
                value = field.value.map(v => {
                    return globalGetDate.format(v, 'YYYY.MM.DD')
                }).toString()
            }
            if (field.oper.endsWith('LIKE') && value[0] === '%') {
                value = value.substring(1, value.length - 1)
            }
            const text = `${name} ${oper} ${value}`
            paramList.push({ level, andOr, text, key: field.key || field.name, name: field.name })
        }
        return {
            paramList,
            removeField,
            clearFields
        }
    }
})
</script>
<style lang="scss">
.operationPanel {
    position: relative;
    z-index: 1;
    width: 100%;
    padding-right: 14px;
    background-color: var(--bg-color);
    border-radius: 5px;
    .operation-main {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    .el-form-item {
        margin-bottom: 0 !important;
        margin-right: 10px !important;
    }

    .operationLeft {
        flex-grow: 1;

        form {
            display: flex;
            align-items: center;
        }
    }

    .operationRight {
        min-width: 20px;
    }

    .field-group {
        border-top: 1px solid #eee;
        margin-top: -1px;
        padding: 10px 20px 0;
        .text {
            border: 1px solid #DCDFE6;
            border-radius: 4px;
            padding: 8px 10px;
            display: inline-block;
            margin-bottom: 10px;
        }
        .andOr {
            padding-left: 10px;
            padding-right: 8px;
        }
        .delete {
            margin-left: 5px;
            &:hover {
                color: #0052d9;
                font-weight: 600;
            }
        }
    }
}
.boxshow-style {
    box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.1);
}
</style>
