<template>
    <div
        class="wrap"
    >
        <el-form
            ref="infoForm"
            class="info-form info-from"
            :style="config.customFormStyle"
            :label-width="config.labelWidth"
            :size="config.size"
            :label-position="config.labelPosition"
            :model="modelData"
            :inline="config.inline"
            :rules="config['validate']"
            :disabled="config.disabled?.()"
            @submit.prevent
            @validate="config.validateCallback"
        >
            <template v-if="config.mode === 'card'">
                <el-card
                    v-for="(card, index) in collapses"
                    :key="index"
                    :shadow="config.cardShadow || 'always'"
                >
                    <template v-slot:header>
                        <div
                            v-if="!!card.title && !card.expandable"
                        >
                            <h4>{{ $t(card.title) }}</h4>
                        </div>
                    </template>
                    <!-- 不可展开的卡片 -->
                    <div
                        :style="cardBodyStyle(card)"
                    >
                        <template
                            v-for="(item, index2) in card.collapses"
                            :key="index2"
                        >
                            <info-form-item
                                v-if="(typeof item.show === 'undefined') ? true : typeof item.show === 'boolean' ? item.show : item.show?.()"
                                :item="item"
                                :test-cy="item.model"
                                :key="index2 + item.model"
                            >
                                <slot
                                    v-if="item.type === 'infoSlot'"
                                    :name="item.slotName"
                                />
                                <component
                                    :is="item.type"
                                    v-else
                                    :row="item"
                                    :modelData="modelData"
                                ></component>
                            </info-form-item>
                        </template>
                    </div>
                </el-card>
            </template>
            <template v-else>
                <template
                    v-for="(item, index) in baseRule"
                    :key="'base' + index"
                >
                    <info-form-item
                        v-if="(typeof item.show === 'undefined') ? true : typeof item.show === 'boolean' ? item.show : item.show?.()"
                        :item="item"
                        :test-cy="item.model"
                        :style="item.customItemStyle"
                        :key="index + item.model"
                    >
                        <slot
                            v-if="item.type === 'infoSlot'"
                            :name="item.slotName"
                        />
                        <component
                            :is="item.type"
                            v-else
                            :row="item"
                            :modelData="modelData"
                        ></component>
                    </info-form-item>
                </template>
                <el-collapse v-if="collapses.length" v-model="cardCollapses">
                    <template
                        v-for="(coll, index) in collapses"
                        :key="'coll' + index"
                    >
                        <el-collapse-item
                            :name="coll.title"
                            :title="$t(coll.title)"
                            :class="[coll.title ? '' : 'hidden-title']"
                            :disabled="!coll.expandable"
                        >
                            <div
                                class="grid"
                                :style="cardBodyStyle(coll)"
                            >
                                <template
                                    v-for="(item, _index) in coll.collapses"
                                    :key="'item' + _index"
                                >
                                    <info-form-item
                                        v-if="(typeof item.show === 'undefined') ? true : typeof item.show === 'boolean' ? item.show : item.show?.()"
                                        :item="item"
                                        :test-cy="item.model"
                                        :key="_index + item.model"
                                    >
                                        <slot
                                            v-if="item.type === 'infoSlot'"
                                            :name="item.slotName"
                                        />
                                        <component
                                            :is="item.type"
                                            v-else
                                            :row="item"
                                            :modelData="modelData"
                                        ></component>
                                    </info-form-item>
                                </template>
                            </div>
                        </el-collapse-item>
                    </template>
                </el-collapse>
            </template>

        </el-form>
    </div>
</template>

<script lang="ts">
import { defineComponent, defineAsyncComponent, computed, reactive, PropType, ref, provide } from 'vue'
import { IBaseForm } from '../form/baseForm'
import { FormInterFace, CollapsesInterFace } from '../form/index'
import InfoFormItem from './infoFormItem.vue'
// import infoAddForm from '../form/addForm/index.vue'
// import infoDynamic from '../form/dynamic/index.vue'
import publicComponent from '../../script/useComponent'
import { ObjectInterface } from '../../script/index'
// form元素
export default defineComponent({
    name: 'InfoForm',
    components: {
        InfoFormItem,
        infoAddForm: defineAsyncComponent(() =>
            import('../form/addForm/index.vue')
        ),
        infoDynamic: defineAsyncComponent(() =>
            import('../form/dynamic/index.vue')
        ),
        ...publicComponent()
    },
    props: {
        config: {
            type: Object as PropType<FormInterFace>,
            required: true
        },
        modelData: {
            type: Object,
            required: true
        }
    },
    setup (props) {
        provide('config', props.config)
        provide('modelData', props.modelData)
        const activeName = ref<string>('1')
        const { rule } = props.config
        const { config } = props
        const infoForm = ref()
        let cardCollapses = reactive<string[]>([])
        const baseRule = computed(() => {
            for (let i = 0; i < config.rule.length; i++) {
                if (config.rule[i].collapse !== undefined) {
                    return config.rule.slice(0, i)
                }
            }
            return config.rule
        })
        const collapses = computed(() => {
            let arr: CollapsesInterFace[] = []
            let title: string[] = []
            let expandable: boolean[] = [] // 是否可展开,默认不可展开
            let sliceIndex: number[] = []
            rule.forEach((item, index) => {
                if (item.collapse !== undefined) {
                    title.push(item.collapse())
                    sliceIndex.push(index)
                    expandable.push(!!item.expandable)
                }
            })
            title.forEach((item, index) => {
                let collapses: IBaseForm[] = []
                if (sliceIndex[index + 1]) {
                    collapses = rule.slice(sliceIndex[index], sliceIndex[index + 1])
                } else {
                    collapses = rule.slice(sliceIndex[index])
                }
                if (rule[sliceIndex[index]].itemsDisabled !== undefined && collapses.length > 0) { // 控制 当前面板的 所有元素
                    collapses.forEach((item: IBaseForm) => {
                        if (item.ignoreItemsDisabled) return
                        if (!item.disabled) {
                            item.disabled = rule[sliceIndex[index]].itemsDisabled
                        } else {
                            const disabled = item.disabled
                            item.disabled = (data) => {
                                return disabled(data) || rule[sliceIndex[index]].itemsDisabled?.()
                            }
                        }
                    })
                }
                let collShow = rule[sliceIndex[index]].collShow?.() // undefined 或 function
                if (collShow !== false) {
                    arr.push({
                        title: title[index],
                        collapses: collapses,
                        expandable: expandable[index]
                    })
                    if (config.allCollapse) {
                        cardCollapses.push(title[index])
                    } else {
                        if (!expandable[index]) {
                            cardCollapses.push(title[index])
                        }
                    }
                }
            })
            return arr
        })
        const cardBodyStyle = (coll: any): ObjectInterface => {
            const columns = config.gridColumns || 1
            const width = 100 / columns + '%'
            let res = {
                'display': 'grid',
                'grid-template-columns': `repeat(${columns}, ${width})`
            }
            if (coll.customItemStyle) {
                Object.assign(res, coll.customItemStyle)
            }
            return res
        }
        const validate = (cb: Function) => {
            return infoForm.value?.validate((valid: boolean, invalidFields) => {
                cb(valid, invalidFields)
                if (!valid) {
                    infoForm.value.scrollToField(Object.keys(invalidFields)[0])
                }
            })
        }
        const resetFields = () => {
            infoForm.value.resetFields()
        }
        const ruleToJson = () => {
            const cyData = {}
            config.rule.forEach((item: ObjectInterface) => {
                let type = item.type
                if (type === 'infoSlot' || type === 'infoDropdown') return
                if (type === 'infoInput') {
                    if (item.button?.show) {
                        type = 'inputButton'
                    } else if (item.select?.show) {
                        type = 'inputSelect'
                    } else if (item.inputType === 'textarea') {
                        type = 'textarea'
                    }
                }
                cyData[item.model] = {
                    label: (typeof item.label === 'function' ? item.label() : item.label) || '',
                    value: '',
                    type: type
                }
                if (item.collapse) {
                    cyData[item.model].advanced = item.collapse
                }
            })
            // eslint-disable-next-line no-console
            console.log(cyData)
        }
        // ruleToJson()
        return {
            config: props.config,
            modelData: props.modelData,
            activeName,
            rule,
            baseRule,
            collapses,
            cardCollapses,
            infoForm,
            validate,
            resetFields,
            cardBodyStyle
        }
    }
})
</script>

<style lang="scss" scoped>
$gutter: 15px;
.wrap {
    padding: 0 0 0 20px;
    .el-card {
        margin-left: -20px;
        border-radius: 8px;
        margin-bottom: 18px;
        >.el-card__body {
            padding-bottom: 2px;
        }
    }
    :deep(.el-collapse) {
        border: 0;
        margin-left: -10px;
        .el-collapse-item {
            .el-collapse-item__header {
                border-bottom: 1px var(--border-color) solid;
                padding-right: 15px;
                padding-left: 10px;
                font-size: 16px;
            }
            .el-collapse-item__wrap {
                border: 0;
                .el-collapse-item__content {
                    padding: $gutter $gutter 0;
                }
            }
            &.is-disabled {
                .el-collapse-item__header {
                    cursor: auto;
                    color: #303133 !important;
                    .el-collapse-item__arrow {
                        display: none;
                    }
                }
            }
        } // item end
    }
    .hidden-title {
        margin-top: -$gutter;
        :deep(.el-collapse-item__header) {
            display: none;
        }
    }
}
:deep(.el-form--label-left .el-form-item.is-required.asterisk-left .el-form-item__label:before) {
    margin-left: -10px
}
:deep(.el-form-item.is-error .is-disabled .el-input__wrapper) {
    box-shadow: 0 0 0 1px var(--ep-color-danger) inset;
}
</style>
