<template>
    <!-- 选项编辑 -->
    <div>
        <!-- 标题和批量编辑 -->
        <div class="title">
            {{ title }}：
            <option-batch-edit
                :link="link"
                :value="value"
                :option="option"
                :option-list.sync="optionList"
                v-if="!hideAdd"
            ></option-batch-edit>
        </div>

        <!-- 选项 -->
        <draggable
            :list="optionList"
            :animation="300"
            handle=".drag"
        >
            <div
                class="option"
                v-for="(item, index) in optionList"
                :key="index"
            >
                <el-radio v-model="option.checked" :label="item.value" v-if="radio"></el-radio>
                <el-checkbox v-model="option.checked" :label="item.value" v-if="checkbox"></el-checkbox>
                <img :src="getFileUrl(item.img)" v-if="img">
                <el-input v-model="item.name" @input="input($event, item.value)"></el-input>
                <i class="iconfont drag">&#xe652;</i>
                <i
                    class="delete el-icon-delete"
                    @click="del(item, index)"
                    v-if="img || optionList.length > 1"
                ></i>
            </div>
        </draggable>

        <!-- 添加选项 -->
        <el-button
            slot="reference"
            type="primary"
            class="add"
            plain
            @click="add"
            v-if="!hideAdd"
        >添加选项</el-button>

        <!-- 添加图片选项 -->
        <el-popover trigger="manual" v-model="formItem.optionError">
            <p class="error">请添加选项</p>
            <el-upload
                slot="reference"
                accept="image/*"
                ref="upload"
                drag
                action
                multiple
                :http-request="upload"
                :show-file-list="false"
                v-if="img"
            >
                <i class="el-icon-upload"></i>
                <div class="el-upload__text tip">将图片拖到此处，或<em>点击上传</em></div>
            </el-upload>
        </el-popover>

        <!-- 选项配置 -->
        <div class="config">
            <div class="left">
                <el-link
                    type="primary"
                    @click="formItem.option.checked = ''"
                    v-if="radio && formItem.option.checked"
                >清除选中</el-link>
            </div>
            <div class="right">
                <option-describe :option="option" v-if="describe"></option-describe>
                <option-link :option="option" v-if="radio">选项关联设置</option-link>
            </div>
        </div>
    </div>
</template>

<script>
import draggable from 'vuedraggable'
import { ossUpload } from '@/assets/utils/ossTool.js'
import { getFileUrl } from '@/assets/utils/host.js'
import ossPaths from '@/assets/ossPaths.js'
const path = ossPaths.form
export default {
    components: {
        draggable,
        OptionBatchEdit: () => import('./components/OptionBatchEdit'),
        OptionDescribe: () => import('./components/OptionDescribe'),
        OptionLink: () => import('./components/OptionLink')
    },
    props: {
        title: { type: String, default: '选项' }, // 标题
        prop: { type: String, default: 'option' }, // 选项属性
        radio: { type: Boolean, default: false }, // 是否是单选
        checkbox: { type: Boolean, default: false }, // 是否是多选
        img: { type: Boolean, default: false }, // 是否有图片
        hideAdd: { type: Boolean, default: false }, // 是否隐藏添加选项
        describe: { type: Boolean, default: false }, // 是否设置选项说明
        unwatch: { type: Boolean, default: false }, // 是否不监听 checked 同步 value
        link: { type: Boolean, default: false } // 是否设置关联选项
    },
    data () {
        const { formItem } = this.$store.state.form
        const option = formItem[this.prop] || {}
        const value = this.prop === 'value'
        return {
            getFileUrl,
            formItem,
            option, // 选项对象
            optionList: value ? option : option.list || [], // 选项列表
            value // 选项是否是 value
        }
    },
    created () {
        this.init()
        this.watch()
    },
    beforeDestroy () {
        if (!this.optionList.length) this.setError(true)
    },
    methods: {
        // 初始化
        init () {
            if (!this.formItem.option && !this.value) {
                const optionList = [...Array(3)].map((n, i) => {
                    const obj = { name: `选项 ${i + 1}`, value: i + 1 }
                    if (this.link) obj.link = []
                    return obj
                })
                const option = {
                    list: this.img ? [] : optionList,
                    nextValue: this.img ? 1 : 4,
                    checked: this.radio ? '' : []
                }
                if (this.img) option.type = 'row'
                this.option = option
                this.optionList = option.list
                this.$set(this.formItem, 'option', option)
            }
            this.$emit('init')
        },
        // 监听 checked 同步 value
        watch () {
            if (this.radio && !this.unwatch) {
                this.$set(this.formItem, 'value', '')
                this.$watch('formItem.option.checked', function (value) {
                    if (this.img) {
                        if (value) {
                            const obj = this.optionList.find(n => n.value === value)
                            this.formItem.value = { value: obj.name, img: obj.img }
                        } else {
                            this.formItem.value = ''
                        }
                    } else {
                        this.formItem.value = value ? this.optionList.find(n => n.value === value).name : ''
                    }
                })
            }
            if (this.checkbox) {
                this.$set(this.formItem, 'value', [])
                this.$watch('formItem.option.checked', function (value) {
                    if (this.img) {
                        this.formItem.value = value.map(item => {
                            const obj = this.optionList.find(n => n.value === item)
                            return { value: obj.name, img: obj.img }
                        })
                    } else {
                        this.formItem.value = value.map(item => this.optionList.find(n => n.value === item).name)
                    }
                })
            }
        },
        // 如果有选中默认值则更新选项时同步 checked
        input (inputVal, value) {
            if (this.option.checked === value) this.formItem.value = inputVal
        },
        // 删除选项，如果有选中默认值则删除
        del (item, index) {
            this.optionList.splice(index, 1)
            if (item.value === this.option.checked) this.option.checked = ''
            if (!this.optionList.length) this.setError(true)
        },
        // 上传图片
        upload ({ file }) {
            file.type.slice(0, 6) === 'image/'
                ? ossUpload({ path, file }).then(this.add)
                : this.$message.warning('请上传图片')
        },
        // 添加选项
        add (res) {
            const obj = {
                name: this.img ? res.name : `${this.title} ${this.optionList.length + 1}`,
                value: this.value ? '' : this.option.nextValue
            }
            if (this.link) obj.link = []
            if (this.img) obj.img = JSON.stringify(res)
            this.optionList.push(obj)
            if (!this.value) this.option.nextValue++
            if (this.formItem.optionError) this.setError(false)
        },
        // 设置校验是否错误
        setError (value) {
            this.formItem.optionHideError = value
            this.formItem.optionError = false // 选项修改时不展示错误，提交时才展示
        }
    }
}
</script>

<style lang="less" scoped>
.option {
    display: flex;
    align-items: center;
    margin-top: 10px;
    .el-radio, .el-checkbox {
        margin-right: 10px;
        /deep/ .el-radio__label, /deep/  .el-checkbox__label {
            display: none;
        }
        /deep/ .el-radio__inner, /deep/ .el-checkbox__inner {
            width: 20px;
            height: 20px;
        }
    }
    .el-radio /deep/ .el-radio__inner::after {
        width: 6px;
        height: 6px;
    }
    .el-checkbox /deep/ .el-checkbox__inner::after {
        width: 5px;
        height: 9px;
        top: 2px;
        left: 6px;
    }
    img {
        width: 32px;
        height: 32px;
        object-fit: contain;
        background-color: #f5f5f5;
        vertical-align: top;
        margin-right: 10px;
    }
    .el-input {
        flex-grow: 1;
        margin-right: 5px;
    }
    .drag, .delete {
        font-size: 20px;
        line-height: 32px;
        padding: 0 5px;
    }
    .drag {
        cursor: move;
        color: #606266;
        &:hover {
            color: #409EFF;
        }
    }
    .delete {
        cursor: pointer;
        &:hover {
            color: #F56C6C;
        }
    }
}
.add {
    width: 60%;
    display: block;
    margin: 10px auto 0;
}
/deep/ .el-upload {
    display: block;
    margin-top: 10px;
    .el-upload-dragger {
        width: 100%;
        height: 100px;
        .el-icon-upload {
            font-size: 60px;
            margin: 10px 0 5px;
        }
    }
}
.config {
    margin-top: 10px;
    display: flex;
    justify-content: space-between;
    .left {
        height: 22px;
    }
    .right {
        display: flex;
        & > div + div {
            margin-left: 10px;
            border-left: 1px solid #DCDFE6;
            padding-left: 10px;
        }
    }
}
.error {
    text-align: center;
    color: #F56C6C;
}
</style>
