<template>
    <div style="display: contents;">
        <template>
            <Col v-for="(column, index) in columns"
                :key="index"
                v-if="column.isShow"
                v-bind="getGrid(column)">
            <div :key="column.code"
                style="height: 82px;"
                v-if="column.controlType === 'Placeholder'"></div>
            <FormItem :label="column.name"
                :key="column.code"
                v-if="column.controlType !== 'Placeholder'">
                <template v-if="column.controlType === 'Label'">
                    <div v-html="showData(data, column.code, column.dataType, column.format)"></div>
                </template>
                <template v-else-if="column.controlType === 'TextInput'">
                    <Input size="small"
                        type="text"
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        @on-keyup="$event => onKeyup($event)"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        :placeholder="column.description" />
                </template>
                <template v-else-if="column.controlType === 'NumberInput'">
                    <Input size="small"
                        type="number"
                        number
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        @on-keyup="$event => onKeyup($event)"
                        :style="{ width: column.controlWidth == null ? '100px' : column.controlWidth + 'px' }"
                        :placeholder="column.description" />
                </template>
                <template v-else-if="column.controlType === 'Select'">
                    <Select size="small"
                        :value="parseFilterData(data, column)"
                        clearable
                        @input="$event => setFilterData(data, column, $event)"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        :placeholder="column.description"
                        :transfer="true"
                        @on-change="onDataChange(column)">
                        <Option v-for="item in getDataSource(data, column)"
                            :key="item.id"
                            :value="item.id">{{ item.name }}</Option>
                    </Select>
                </template>
                <template v-else-if="column.controlType === 'ComboSelect'">
                    <Select size="small"
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        clearable
                        filterable
                        remote
                        :remote-method="search => loadOption(data, column, search)"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        :placeholder="column.description"
                        :transfer="true"
                        @on-change="onDataChange(column)">
                        <Option v-for="item in getDataSource(data, column)"
                            :key="item.id"
                            :value="item.id">{{ item.name }}</Option>
                    </Select>
                </template>
                <template v-else-if="column.controlType === 'DialogSelect'">
                    <Input size="small"
                        type="text"
                        readonly
                        :value="showSelected(data, column)"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        @on-focus="dialogSelectOpen(data, column)"
                        @on-clear="dialogSelectRemove(data, column)">
                    <Button slot="prepend"
                        custom-icon="fa fa-search"
                        @click="dialogSelectOpen(data, column)"></Button>
                    </Input>
                </template>
                <template v-else-if="
                            column.controlType === 'Date' ||
                            column.controlType === 'DateTime' ||
                            column.controlType === 'Year' ||
                            column.controlType === 'Month' ||
                            column.controlType === 'DateRange'
                        ">
                    <DatePicker size="small"
                        :type="column.controlType.toLowerCase()"
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        :placeholder="column.description"
                        :transfer="true"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        @on-change="onDataChange(column)"></DatePicker>
                </template>
                <template v-else-if="column.controlType === 'Time'">
                    <TimePicker size="small"
                        type="time"
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        :placeholder="column.description"
                        :transfer="true"
                        :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
                        @on-change="onDataChange(column)"></TimePicker>
                </template>
                <template v-else-if="column.controlType === 'Check'">
                    <Checkbox size="small"
                        :value="!!parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        @on-change="onDataChange(column)" />
                </template>
                <template v-else-if="column.controlType === 'Switch'">
                    <Switch size="small"
                        :value="!!parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        @on-change="onDataChange(column)" />
                </template>
                <template v-else-if="column.controlType === 'Radio'">
                    <RadioGroup size="small"
                        :value="parseFilterData(data, column)"
                        @input="$event => setFilterData(data, column, $event)"
                        @on-change="onDataChange(column)">
                        <Radio v-for="item in getDataSource(data, column)"
                            :key="item.id"
                            :label="item.id">
                            <span>{{ item.name }}</span>
                        </Radio>
                    </RadioGroup>
                </template>
            </FormItem>
            </Col>
            <Col v-if="keywordEnable"
                v-bind="grid6">
            <FormItem label="关键词">
                <Input v-model="data.keyword"
                    v-focus
                    @on-keyup="$event => onKeyup($event)"
                    size="small" />
            </FormItem>
            </Col>
        </template>
    </div>
</template>
<script>
    import mixinPage from '../../mixins/page';
    import mixin from './mixin';
    import modelApi from '../../api/model';

    export default {
        mixins: [mixin, mixinPage],
        components: {},
        data() {
            return {};
        },
        async created() {
            this.init();
        },
        props: {
            keywordEnable: {
                type: Boolean
            },
            // 筛选项数据
            data: {
                type: Object
            },
            // 字段
            columns: {
                type: Array
            }
        },
        computed: {},
        methods: {
            init() {
                // 初始化触发规则
                setTimeout(() => {
                    this.initTrigger();

                    this.onDataChange();
                });
            },
            // 初始化触发规则
            initTrigger() {
                // 触发规则
                this.columns.forEach(column => {
                    column.triggers = [];
                });

                this.columns
                    .filter(column => {
                        return column.source != null && column.source.trim() !== '' && column.param != null && column.param.trim() !== '';
                    })
                    .forEach(column => {
                        let param = JSON.parse(column.param);
                        for (let key in param) {
                            this.columns
                                .filter(item => {
                                    return param[key] === item.code;
                                })
                                .forEach(item => {
                                    item.triggers.push(column);
                                });
                        }
                    });
            },
            // 填充数据源
            async fillDataSource(data, column, param) {
                // 参数完整，查询数据
                let res = await modelApi.query(column.source, param);

                column.dataSource = res.data.map(item => {
                    return {
                        id: column.sourceDataCode == null || column.sourceDataCode.trim() === '' ? item.id : this.parseData(item, column.sourceDataCode),
                        name: this.parseData(item, column.sourceDisplayCode)
                    };
                });

                // 默认第一项
                if (data) {
                    if (this.parseFilterData(data, column) == null && column.isDefaultFirst && res.length > 0) {
                        this.setData(data, column.code, this.parseData(res[0], column.sourceDataCode));
                    }
                }

                this.$forceUpdate();

                // 更新data触发刷新
                // this.data = { ...this.data };

                // 触发
                this.onDataChange(column);
            },
            // 获取数据源
            getDataSource(data, column) {
                if (column.dataType.indexOf('Enum:') === 0) {
                    // 枚举
                    return this.getEnumList(column.dataType.split(':')[1]);
                } else {
                    return column.dataSource;
                }
            },
            // 可筛选下拉框加载数据
            loadOption(data, column, keyword) {
                let param = this.getParam(data, column);

                if (param != null) {
                    if ((keyword == null || keyword.trim() === '') && this.parseFilterData(data, column) != null) {
                        param.id = this.parseFilterData(data, column);
                    } else {
                        param.keyword = keyword;
                    }
                    param.per = 20;

                    this.fillDataSource(data, column, param);
                } else {
                    // 参数不完整，清空数据
                    column.dataSource = [];
                    this.setData(data, column.code, null);
                    // column.displayValue = null;

                    // 触发
                    column.triggers.forEach(item => {
                        item.needRefresh = true;
                    });
                }
            },
            // 数据变化事件
            onDataChange(sender, selected) {
                setTimeout(() => {
                    this.$emit('on-change', sender, selected);
                });

                // 计算需要刷新的字段
                if (sender == null || sender.triggers !== []) {
                    this.columns.forEach(function (column) {
                        if (
                            column.source != null &&
                            column.source.trim() !== '' &&
                            (sender == null ||
                                sender.triggers.some(item => {
                                    return item.id === column.id;
                                }))
                        ) {
                            column.needRefresh = true;
                        }
                    });
                }

                // 刷新数据源
                while (true) {
                    let column = this.columns.filter(item => {
                        return item.needRefresh === true;
                    })[0];

                    if (column == null) {
                        // 没有需要刷新的字段
                        break;
                    }

                    let param = this.getParam(this.data, column);

                    if (column.controlType === 'Select' || column.controlType === 'Radio') {
                        // 选择框、单选框组
                        if (param != null) {
                            this.fillDataSource(this.data, column, param);
                        } else {
                            // 参数不完整，清空数据
                            column.dataSource = [];
                            this.setData(this.data, column.code, null);
                            // column.displayValue = null;

                            // 触发
                            column.triggers.forEach(item => {
                                item.needRefresh = true;
                            });
                        }
                    } else if (column.controlType === 'ComboSelect') {
                        // 可筛选选择框
                        this.loadOption(this.data, column);
                    }

                    column.needRefresh = false;
                }
            },
            // 筛选项取值
            parseFilterData(model, column) {
                return model[this.getFilterKey(column)];
            },
            // 筛选项赋值
            setFilterData(model, column, value) {
                model[this.getFilterKey(column)] = value;
            },
            // 获取筛选项Key
            getFilterKey(column) {
                switch (column.operator) {
                    case 'GreaterThan':
                        return column.code + '_g'; // 大于
                    case 'LessThan':
                        return column.code + '_l'; // 小于
                    case 'GreaterThanOrEqual':
                        return column.code + '_ge'; // 大于等于
                    case 'LessThanOrEqual':
                        return column.code + '_le'; // 小于等于
                    case 'NotEqual':
                        return column.code + '_n'; // 不等于
                    case 'Contains':
                        return column.code + '_c'; // 模糊匹配
                    default:
                        return column.code; // 其他，包括等于、自定义等
                }
            },
            // 键盘事件
            onKeyup(e) {
                this.$emit('on-keyup', e);
            }
        }
    };
</script>
