<template>
    <!-- 控件列表 -->
    <div class="form-item">
        <!-- 控件管理 -->
        <i
            class="set el-icon-setting"
            :class="{ active: show }"
            @click="show = !show"
            v-if="isDev"
        ></i>
        <div style="padding-bottom: 10px;" v-if="show">
            <el-tooltip>
                <div slot="content">
                    <p>控件管理功能仅在开发环境使用</p>
                    <p>开发环境下可操作控件：</p>
                    <p>- 添加控件</p>
                    <p>- 控件上右键编辑控件</p>
                    <p>- 拖拽控件改变顺序（先开启排序）</p>
                </div>
                <i class="el-icon-info" style="font-size: 24px; vertical-align: middle; margin-right: 10px;"></i>
            </el-tooltip>
            <el-button type="primary" icon="el-icon-plus" @click="addOrEdit()">添加控件</el-button>
            <span style="margin-right: 20px;"></span>
            <el-switch v-model="isSort" active-text="启用排序" inactive-text="禁用排序"></el-switch>
        </div>

        <!-- 切换控件或大纲 -->
        <div class="switch">
            <el-radio-group v-model="isControl" v-if="toc">
                <el-radio-button :label="true">控件</el-radio-button>
                <el-radio-button :label="false">大纲</el-radio-button>
            </el-radio-group>
        </div>

        <!-- 控件 -->
        <template v-if="isControl">
            <div v-for="(listItem, listIndex) in list" :key="listIndex">
                <div class="title">{{ listItem.title }}</div>
                <draggable
                    tag="ul"
                    v-model="listItem.list"
                    filter=".disabled"
                    :class="{ 'no-transition': !isSort }"
                    :group="{ name: 'form', pull: 'clone', put: false }"
                    :clone="clone"
                    :sort="isSort"
                    :animation="300"
                    @update="sort(listIndex)"
                    @start="listItem.list[$event.oldIndex].type === 'subform' ? $emit('start') : ''"
                    @end="listItem.list[$event.oldIndex].type === 'subform' ? $emit('end') : ''"
                >
                    <li
                        v-for="(item, index) in listItem.list"
                        :key="index"
                        :class="[item.type, { disabled: !item.enabled }]"
                    >
                        <div
                            class="item"
                            @click="item.enabled && $emit('add', clone(item))"
                            @contextmenu="addOrEdit(item)"
                        >
                            <i class="iconfont" v-html="item.icon"></i>{{ item.name }}
                        </div>
                    </li>
                </draggable>
            </div>
        </template>

        <!-- 大纲 -->
        <el-tree
            :data="dataList"
            :props="{ label: 'title', children: 'list' }"
            default-expand-all
            v-else
        ></el-tree>

        <!-- 添加或编辑控件 -->
        <el-dialog :title="`${ isAdd ? '添加' : '编辑'}控件`" width="480px" :visible.sync="visible">
            <el-form :model="form" :rules="rules" label-width="7em" ref="form" style="padding: 0 50px">
                <el-form-item label="控件名称" prop="name">
                    <el-input v-model.trim="form.name"></el-input>
                </el-form-item>
                <el-form-item label="控件类型" prop="category">
                    <el-input v-model.trim="form.category"></el-input>
                </el-form-item>
                <el-form-item label="控件组名" prop="controls_group">
                    <el-radio-group v-model="form.controls_group">
                        <el-radio label="Basic"></el-radio>
                        <el-radio label="Heighten"></el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="控件适用" prop="applicable">
                    <el-radio-group v-model="form.applicable">
                        <el-radio label="Form"></el-radio>
                        <el-radio label="Question"></el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="启用禁用" v-if="!isAdd">
                    <el-switch
                        v-model="form.enabled"
                        :active-value="1"
                        :inactive-value="0"
                        active-text="启用"
                        inactive-text="禁用"
                        inactive-color="#F56C6C"
                        @change="enabled"
                    ></el-switch>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="danger" @click="del" style="float: left;" v-if="!isAdd">删 除</el-button>
                <el-button type="primary" @click="submit">保 存</el-button>
                <el-button @click="visible = false">取 消</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import draggable from 'vuedraggable'
import { v1 as uuidv1 } from 'uuid'
export default {
    name: 'FormControl',
    components: { draggable },
    props: {
        toc: { type: Boolean, default: false },
        dataList: { type: Array, default: () => [] },
        applicable: { type: String, default: 'Form' }
    },
    data () {
        const form = {
            name: '',
            category: '',
            controls_group: '',
            applicable: ''
        }
        const rules = {}
        for (let key in form) rules[key] = { required: true, message: '必填' }
        return {
            isDev: process.env.NODE_ENV === 'development',
            show: false, // 是否可管理
            isAdd: false, // 是添加还是编辑
            isSort: false, // 是否可改变顺序
            visible: false, // 是否显示弹窗
            form, // 弹窗表单
            rules, // 弹窗校验

            isControl: true, // 切换控件和大纲
            list: [], // 控件列表
            inputsReg: /^(input|textarea)$/,
            selectsReg: /^(radio|checkbox|date|dateRange|address|gradeClass)$/,
            icon: {
                input: '&#xe64f;',
                textarea: '&#xe64c;',
                radio: '&#xe647;',
                checkbox: '&#xe645;',
                date: '&#xe643;',
                address: '&#xe641;',
                contacts: '&#xe651;',
                info: '&#xe64b;',
                subform: '&#xe642;',

                dateRange: '&#xe64a;',
                img: '&#xe649;',
                file: '&#xe636;',
                calculate: '&#xe644;',

                radioText: '&#xe640;',
                checkboxText: '&#xe648;',
                radioImg: '&#xe64e;',
                checkboxImg: '&#xe649;',
                radioMatrix: '&#xe660;',
                rate: '&#xe65f;',
                sort: '&#xe661;',
                gradeClass: '&#xe60f;'
                // page: '&#xe646;',
                // link: '&#xe639;'
            }
        }
    },
    created () {
        this.getList()
    },
    methods: {
        // 获取控件列表
        getList () {
            this.$api.commonApi.formControlsList({
                applicable: this.applicable // 传空字符串可获取全部
            }).then(res => {
                const { Status: status, Data: list } = res.data
                if (status) {
                    list.forEach((item, index) => {
                        list[index].type = item.category
                        list[index].icon = this.icon[item.category]
                    })
                    const basicList = list.filter(item => item.controls_group === 'Basic')
                    const heightenList = list.filter(item => item.controls_group === 'Heighten')
                    this.list = []
                    if (basicList.length) this.list.push({ title: '基本控件', list: basicList })
                    if (heightenList.length) this.list.push({ title: '增强控件', list: heightenList })
                }
            })
        },
        // 克隆前组件的配置
        clone (item) {
            const obj = {
                uuid: uuidv1(),
                type: item.type,
                name: item.name,
                title: item.name
            }
            if (this.inputsReg.test(item.type)) obj.placeholder = '请输入'
            if (this.selectsReg.test(item.type)) obj.placeholder = '请选择'
            if (item.type === 'dateRange') {
                obj.title = '开始时间'
                obj.title2 = '结束时间'
                obj.placeholder2 = '请选择'
            }
            if (item.type === 'address') obj.placeholder2 = '详细地址'
            if (item.type === 'contacts') obj.placeholder = '添加'
            if (item.type === 'info') obj.title = obj.placeholder = ''
            if (item.type === 'subform') {
                obj.list = []
                obj.value = '增加'
            }
            if (item.type === 'calculate') obj.placeholder = '自动计算数值'
            return obj
        },
        // 添加或编辑
        addOrEdit (item) {
            if (this.show) {
                event.preventDefault()
                this.isAdd = !item
                this.form = item || {}
                this.visible = true
                this.$nextTick(() => {
                    if (this.$refs.form) this.$refs.form.clearValidate()
                })
            }
        },
        // 提交
        submit (item) {
            this.$refs.form.validate().then(() => {
                this.isAdd ? this.add() : this.edit()
            }).catch(() => {})
        },
        // 添加控件
        add () {
            this.$api.commonApi.formControlsCreate(this.form).then(res => this.then(res, '添加'))
        },
        // 编辑控件
        edit () {
            this.$api.commonApi.formControlsUpdate({
                b_id: this.form.b_id,
                ...this.form
            }).then(res => this.then(res, '编辑'))
        },
        // 启用禁用控件
        enabled (enabled) {
            this.$api.commonApi.formControlsSetEnabled({
                b_id: this.form.b_id,
                enabled
            }).then(res => this.then(res, enabled ? '启用' : '禁用'))
        },
        // 删除控件
        del () {
            this.$api.commonApi.formControlsDelete({
                b_id: this.form.b_id
            }).then(res => this.then(res, '删除'))
        },
        // 统一回调
        then (res, text) {
            if (res.data.Status) {
                this.getList()
                this.visible = false
                this.$message.success('已' + text)
            }
        },
        // 排序
        sort (index) {
            const params = this.list[index].list.map((item, index) => ({ b_id: item.b_id, sort_code: index }))
            this.$api.commonApi.formControlsSort(params).then(res => {
                if (!res.data.Status) {
                    this.$message('排序失败，请重试')
                    this.getList()
                }
            })
        }
    }
}
</script>

<style lang="less" scoped>
.form-item {
    padding: 10px 15px;
    position: relative;
    .switch {
        text-align: center;
    }
    .el-tree {
        padding-top: 10px;
    }
}
.title {
    padding: 5px;
}
ul {
    display: flex;
    flex-wrap: wrap;
    &.no-transition li {
        transition-duration: 0s !important;
    }
    li {
        width: 50%;
        padding: 5px;
        .item {
            padding: 5px 10px;
            background-color: #F4F4F5;
            i {
                margin-right: 10px;
                font-size: 16px;
            }
        }
        &:not(.disabled):hover .item {
            background-color: #ccc;
            cursor: move;
        }
        &.disabled .item {
            opacity: 0.5;
            cursor: not-allowed;
        }
    }
}
.set {
    position: absolute;
    top: 3px;
    left: 3px;
    font-size: 16px;
    transition-duration: 0.3s;
    cursor: pointer;
    &.active {
        color: #409EFF;
        transform: rotate(90deg);
    }
}
</style>
