<template>
  <div>
    <Modal v-model="opened" scrollable :mask-closable="layout.maskClosable" :draggable="layout.draggable" :sticky="true" :reset-drag-position="true" width="800">
      <div slot="header">
        <span class="title">筛选项设置</span>
        <span class="description">Filter Setting</span>
      </div>
      <div class="ivu-ml-8 ivu-mr-8">
        <Form ref="form" :model="data" label-position="top" label-colon="：" class="ivu-mt" :rules="rules" @submit.native.prevent>
          <Row :gutter="24" type="flex">
            <Col v-bind="grid8" v-if="!dataView.isVirtual">
              <FormItem label="字段" key="code" prop="code">
                <Input type="text" v-if="data.operator != 'Custom'" readonly v-model="data.code" @on-focus="openSelect()">
                  <Button slot="prepend" custom-icon="fa fa-search" @click="openSelect()"></Button>
                </Input>
                <Input type="text" v-if="data.operator == 'Custom'" v-model="data.code" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="dataView.isVirtual">
              <FormItem label="字段代码" key="code" prop="code">
                <Input type="text" v-model="data.code" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="名称" key="name" prop="name">
                <Input type="text" v-model="data.name" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="dataView.isVirtual == true">
              <FormItem label="字段类型" key="dataType" prop="dataType">
                <Select v-model="data.dataType" :transfer="true">
                  <Option v-for="item in getEnumList('DataType')" :key="item.id" :value="item.id">{{ item.name }}</Option>
                </Select>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="dataView.isVirtual != true">
              <FormItem label="字段类型" key="dataType" prop="dataType">
                {{ data.dataType }}
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="!dataView.isDataSource">
              <FormItem label="操作符" key="operator" prop="operator">
                <Select v-model="data.operator" :transfer="true">
                  <Option v-for="item in getEnumList('Operator')" :key="item.id" :value="item.id">{{ item.name }}</Option>
                </Select>
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="控件类型" key="controlType" prop="controlType">
                <Select v-model="data.controlType" :transfer="true" @on-change="controlTypeChange">
                  <Option v-for="item in getEnumList('ControlType')" :key="item.id" :value="item.id">{{ item.name }}</Option>
                </Select>
              </FormItem>
            </Col>
            <Col
              v-bind="grid8"
              v-if="
                data.controlType == 'Select' ||
                data.controlType == 'MultiSelect' ||
                data.controlType == 'SelectWithOther' ||
                data.controlType == 'ComboSelect' ||
                data.controlType == 'Radio' ||
                data.controlType == 'CheckGroup'
              "
            >
              <FormItem label="固定选项" key="isStaticItem" prop="isStaticItem">
                <Switch
                  :value="!!data.isStaticItem"
                  @input="
                    $event => {
                      data.isStaticItem = $event;
                      $forceUpdate();
                    }
                  "
                />
              </FormItem>
            </Col>
            <Col
              v-bind="grid24"
              v-if="
                data.isStaticItem &&
                (data.controlType == 'Select' ||
                  data.controlType == 'MultiSelect' ||
                  data.controlType == 'SelectWithOther' ||
                  data.controlType == 'ComboSelect' ||
                  data.controlType == 'Radio' ||
                  data.controlType == 'CheckGroup')
              "
            >
              <FormItem label="选项内容（每一行为一项，key/value用冒号分隔，没有冒号表示key/value一致）" key="itemData" prop="itemData">
                <Input type="textarea" :rows="5" v-model="data.itemData" />
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="needDataSource && data.controlType != 'DialogSelect' && data.controlType != 'MultiDialogSelect'">
              <FormItem label="数据源" key="source" prop="source">
                <dialog-select
                  ref="select"
                  v-model="data.source"
                  source="EntitySelect"
                  source-data-code="name"
                  source-display-code="name"
                  @on-change="sourceChange"
                ></dialog-select>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="data.controlType == 'DialogSelect' || data.controlType == 'MultiDialogSelect'">
              <FormItem label="视图" key="dataViewSource" prop="source">
                <dialog-select
                  ref="dataViewSource"
                  v-model="data.source"
                  source="DataViewSelect"
                  source-data-code="code"
                  source-display-code="code"
                  :param="{ viewType: 'TableView' }"
                  @on-change="sourceChange"
                ></dialog-select>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="data.source && needDataSource">
              <FormItem label="数据字段" key="sourceDataCode" prop="sourceDataCode">
                <Input type="text" :readonly="true" v-model="data.sourceDataCode" @on-focus="openColumnSelect(data, 'sourceDataCode')">
                  <Button slot="prepend" custom-icon="fa fa-search" @click="openColumnSelect(data, 'sourceDataCode')"></Button>
                </Input>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="data.source && needDataSource">
              <FormItem label="显示字段" key="sourceDisplayCode" prop="sourceDisplayCode">
                <Input type="text" :readonly="true" v-model="data.sourceDisplayCode" @on-focus="openColumnSelect(data, 'sourceDisplayCode')">
                  <Button slot="prepend" custom-icon="fa fa-search" @click="openColumnSelect(data, 'sourceDisplayCode')"></Button>
                </Input>
              </FormItem>
            </Col>
            <Col v-bind="grid16" v-if="data.source && needDataSource">
              <FormItem label="参数" key="param" prop="param">
                <Input type="text" @click.native="paramOpen" :readonly="true" v-model="data.param" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="是否显示" key="isShow" prop="isShow">
                <Switch
                  :value="!!data.isShow"
                  @input="
                    $event => {
                      data.isShow = $event;
                    }
                  "
                />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="栏目宽度" key="columnWidth" prop="columnWidth">
                <Select v-model="data.columnWidth" :transfer="true">
                  <Option v-for="item in getEnumList('ColumnWidth')" :key="item.id" :value="item.id">{{ item.name }}</Option>
                </Select>
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="控件宽度" key="controlWidth" prop="controlWidth">
                <Input type="number" style="width: 100px" number v-model="data.controlWidth" />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="默认值" key="defaultValue" prop="defaultValue">
                <Input type="text" v-model="data.defaultValue" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="描述" key="description" prop="description">
                <Input type="text" v-model="data.description" maxlength="200" />
              </FormItem>
            </Col>
          </Row>
        </Form>
      </div>
      <div slot="footer">
        <Button type="primary" custom-icon="fa fa-check" @click="finish">{{ $t('Front_Btn_OK') }}</Button>
        <Button type="default" custom-icon="fa fa-times" @click="close">{{ $t('Front_Btn_Close') }}</Button>
      </div>
    </Modal>
    <Modal v-model="paramOpened" scrollable :mask-closable="layout.maskClosable" :draggable="layout.draggable" :sticky="true" :reset-drag-position="true" width="600">
      <div slot="header">
        <slot name="header">
          <span class="title">参数</span>
          <span class="description">Param</span>
        </slot>
      </div>
      <div class="i-table-no-border">
        <Table :columns="parpamColumns" :data="params" stripe size="small" no-data-text="暂无数据...">
          <template slot-scope="{ index }" slot="command">
            <Button size="small" :title="$t('Front_Btn_Edit')" type="primary" ghost custom-icon="fa fa-edit" @click="paramEdit(params[index], index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Up')" type="primary" ghost custom-icon="fa fa-chevron-up" @click="upParam(params[index], index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Down')" type="primary" ghost custom-icon="fa fa-chevron-down" @click="downParam(params[index], index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Remove')" type="primary" ghost custom-icon="fa fa-times" @click="paramRemove(params[index], index)"></Button>
          </template>
        </Table>
      </div>
      <div slot="footer">
        <Button type="primary" ghost custom-icon="fa fa-plus" @click="paramEdit()">{{ $t('Front_Btn_Add') }}</Button>
        <Button type="primary" custom-icon="fa fa-check" @click="paramSave">{{ $t('Front_Btn_OK') }}</Button>
      </div>
    </Modal>
    <Modal v-model="paramItemOpened" scrollable :mask-closable="layout.maskClosable" :draggable="layout.draggable" :sticky="true" :reset-drag-position="true" width="800">
      <div slot="header">
        <span class="title">参数设置</span>
        <span class="description">Param Setting</span>
      </div>
      <div class="ivu-ml-8 ivu-mr-8">
        <Form ref="paramItemForm" :rules="paramItemFormRules" :model="paramData" label-position="top" label-colon="：" class="ivu-mt" @submit.native.prevent>
          <Row :gutter="24" type="flex">
            <Col v-bind="grid8">
              <FormItem label="字段" key="code" prop="code">
                <Input type="text" v-model="paramData.code">
                  <Button slot="prepend" custom-icon="fa fa-search" @click="openColumnSelect(paramData, 'code')"></Button>
                </Input>
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem label="字段类型" key="keyType" prop="keyType">
                <RadioGroup v-model="paramData.keyType" @on-change="keyTypeChange">
                  <Radio label="常量"></Radio>
                  <Radio label="变量"></Radio>
                </RadioGroup>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="paramData.keyType == '常量'">
              <FormItem label="值" key="val" prop="val">
                <Input type="text" v-model="paramData.val" />
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="paramData.keyType == '变量'">
              <FormItem label="值" key="val2" prop="val">
                <Input type="text" v-model="paramData.val" @on-focus="openValueSelect">
                  <Button slot="prepend" custom-icon="fa fa-search" @click="openValueSelect"></Button>
                </Input>
              </FormItem>
            </Col>
          </Row>
        </Form>
      </div>
      <div slot="footer">
        <Button type="primary" custom-icon="fa fa-check" @click="paramItemSave">{{ $t('Front_Btn_OK') }}</Button>
        <Button type="default" custom-icon="fa fa-times" @click="paramItemClose">{{ $t('Front_Btn_Close') }}</Button>
      </div>
    </Modal>
    <column-check ref="columnCheck" />
    <column-check ref="columnParamCheck" />
  </div>
</template>
<script>
  import mixinPage from '../../mixins/page';
  import columnCheck from './column-check';

  export default {
    mixins: [mixinPage],
    components: { columnCheck },
    data() {
      return {
        data: {},
        opened: false,
        callback: null,
        default: {
          code: null,
          name: null,
          operator: 'Equal',
          controlType: null,
          isShow: true,
          columnWidth: 'Column3',
          source: null,
          sourceDataCode: null,
          sourceDisplayCode: null
        },
        rules: {
          code: {
            type: 'string',
            required: true,
            message: '请输入字段',
            trigger: 'blur,change'
          },
          name: {
            type: 'string',
            required: true,
            message: '请输入名称',
            trigger: 'blur,change'
          },
          operator: {
            type: 'string',
            required: true,
            message: '请输入操作符',
            trigger: 'blur,change'
          },
          controlType: {
            type: 'string',
            required: true,
            message: '请输入控件类型',
            trigger: 'blur,change'
          },
          columnWidth: {
            type: 'string',
            required: true,
            message: '请输入栏目宽度',
            trigger: 'blur,change'
          },
          source: {
            type: 'string',
            required: true,
            message: '请输入数据源/视图',
            trigger: 'blur,change'
          },
          sourceDataCode: {
            type: 'string',
            required: true,
            message: '请输入数据字段',
            trigger: 'blur,change'
          },
          sourceDisplayCode: {
            type: 'string',
            required: true,
            message: '请输入显示字段',
            trigger: 'blur,change'
          }
        },
        parpamColumns: [
          { title: '参数', resizable: true, align: 'center', key: 'code' },
          { title: '值', align: 'center', resizable: true, key: 'val' },
          { slot: 'command', title: ' ', align: 'center', resizable: true, fixed: 'right' }
        ],
        params: [],
        paramData: {},
        paramItemFormRules: {
          code: {
            type: 'string',
            required: true,
            message: '请输入字段名称',
            trigger: 'blur,change'
          },
          keyType: {
            type: 'string',
            required: true,
            message: '请选择字段类型',
            trigger: 'blur,change'
          },
          val: {
            type: 'string',
            required: true,
            message: '请输入值',
            trigger: 'blur,change'
          }
        },
        paramOpened: false,
        paramItemOpened: false,
        sourceBefore: null,
        //controlTypeBefore: null,
        currentColumn: null
      };
    },
    async created() {},
    props: {
      // 数据视图
      dataView: {
        type: Object
      }
    },
    computed: {
      // 选择框，或复选框组，且非枚举类型，需要输入数据源
      needDataSource() {
        if (this.data) {
          return (
            ((this.data.controlType === 'Select' ||
              this.data.controlType === 'MultiSelect' ||
              this.data.controlType === 'TreeSelect' ||
              this.data.controlType === 'MultiTreeSelect' ||
              this.data.controlType === 'SelectWithOther' ||
              this.data.controlType === 'ComboSelect' ||
              this.data.controlType === 'Radio' ||
              this.data.controlType === 'CheckGroup') &&
              !this.data.isStaticItem &&
              this.data.dataType &&
              this.data.dataType.indexOf('Enum:') !== 0) ||
            this.data.controlType === 'DialogSelect' ||
            this.data.controlType === 'MultiDialogSelect'
          );
        } else {
          return false;
        }
      }
    },
    methods: {
      // 打开
      open(row, callback) {
        if (row) {
          this.data = this.copy(row);
        } else {
          this.data = this.copy(this.default);
          this.data['dataView'] = this.dataView;
        }
        if (this.dataView.isDataSource) {
          this.data.operator = 'Equal';
        }

        // 清空验证
        setTimeout(() => {
          this.$refs.form.fields.forEach(field => {
            field.validateState = '';
            field.validateMessage = '';
          });
        });

        this.callback = callback;
        this.opened = true;
      },
      // 关闭
      close() {
        this.opened = false;
      },
      // 确认
      async finish() {
        let isOK = await this.$refs.form.validate();

        if (!isOK) {
          this.error('Front_Msg_Form_Validate_Fail');
        } else {
          if (this.data.operator === 'Custom') {
            this.data.dataType = 'String';
          }

          this.callback(this.copy(this.data));
          this.opened = false;
        }
      },
      // 打开字段选择界面
      openSelect() {
        if (this.dataView.isDataSource) {
          // 存储过程
          this.$refs.columnCheck.openDataSourceFilter(this.dataView.dataSource, checked => {
            this.currentColumn = checked;

            this.data.code = this.currentColumn.code;
            this.data.name = this.currentColumn.name;
            this.data.dataType = this.currentColumn.dataType;

            setTimeout(() => {
              this.$forceUpdate();
            });
          });
        } else {
          // 非存储过程
          this.$refs.columnCheck.open(this.dataView.model, checked => {
            this.currentColumn = checked;

            this.data.code = this.currentColumn.code;
            this.data.name = this.currentColumn.name;
            this.data.dataType = this.currentColumn.dataType;

            if (this.currentColumn.objColumn) {
              this.data.source =
                this.data.controlType == 'DialogSelect' || this.data.controlType == 'MultiDialogSelect'
                  ? this.currentColumn.objColumn.dataType + 'Select'
                  : this.currentColumn.objColumn.dataType;
              this.data.sourceDataCode = 'id';
              this.data.sourceDisplayCode = this.currentColumn.objColumn.columns.some(column => {
                return column.code === this.currentColumn.objColumn.code + '.name';
              })
                ? 'name'
                : null;
            }

            setTimeout(() => {
              this.$forceUpdate();
            });
          });
        }
      },
      // 数据源变更
      sourceChange() {
        if (this.sourceBefore != this.data.source) {
          this.data.sourceDisplayCode = null;
          this.data.sourceDataCode = null;
          this.data.param = null;
        }
        this.sourceBefore = this.data.source;

        setTimeout(() => {
          this.$forceUpdate();
        });
      },
      // 打开变量字段选择界面
      openValueSelect() {
        this.$refs.columnCheck.open(this.data.dataView.model, checked => {
          this.paramData.val = checked.code;
          this.$forceUpdate();
        });
      },
      // 打开参数弹框
      paramOpen() {
        this.params = [];
        this.paramOpened = true;
        if (this.data.param != null && this.data.param != '') {
          let obj = JSON.parse(this.data.param);
          for (let key in obj) {
            let type = '变量';
            if (obj[key].indexOf('[') == 0 && obj[key].indexOf(']') + 1 == obj[key].length) {
              type = '常量';
            }
            this.params.push({
              code: key,
              val: obj[key],
              type: type
            });
          }
        }
      },
      // 参数框确认
      async paramItemSave() {
        let isOK = await this.$refs.paramItemForm.validate();

        if (!isOK) {
          this.error('Front_Msg_Form_Validate_Fail');
          return;
        }
        let val = this.paramData.val;

        if (this.paramData.keyType == '常量') {
          let len = this.paramData.val.length;
          val = this.paramData.val.padStart(len + 1, '[').padEnd(len + 2, ']');
        }

        if (this.paramData.source) {
          this.paramData.source.code = this.paramData.code;
          this.paramData.source.val = val;
          this.paramData.source.type = this.paramData.keyType;
        } else {
          this.params.push({
            code: this.paramData.code,
            val: val,
            type: this.paramData.keyType
          });
        }
        this.paramItemOpened = false;
        this.$refs.paramItemForm.resetFields();
      },
      paramItemClose() {
        this.paramItemOpened = false;
        this.$refs.paramItemForm.resetFields();
      },
      keyTypeChange() {
        setTimeout(() => {
          this.paramData.val = null;
          this.$forceUpdate();
        });
      },
      // 打开字段选择界面
      openColumnSelect(data, code) {
        if (this.data.source == null) {
          return;
        }

        let model;
        if (this.data.controlType == 'DialogSelect' || this.data.controlType == 'MultiDialogSelect') {
          model = this.$refs.dataViewSource.selectedData.model;
        } else {
          model = this.data.source;
        }

        this.$refs.columnParamCheck.open(model, checked => {
          data[code] = checked.code;
          this.$forceUpdate();
        });
      }, // 保存参数
      paramSave() {
        let obj = {};
        this.params.forEach(item => {
          obj[item.code] = item.val;
        });
        this.data.param = this.params.length > 0 ? JSON.stringify(obj) : '';
        this.paramOpened = false;
      },
      // 编辑参数项
      paramEdit(row) {
        if (row) {
          this.paramData = {
            code: row.code,
            val: row.val.replace('[', '').replace(']', ''),
            keyType: row.type,
            source: row
          };
        } else {
          this.paramData = {
            code: '',
            val: '',
            keyType: '常量'
          };
        }
        this.paramItemOpened = true;
      }, // 上移参数项
      upParam(row, index) {
        if (index > 0) {
          this.params.splice(index, 1);
          this.params.splice(index - 1, 0, row);
        }
      },
      // 下移参数项
      downParam(row, index) {
        if (index < this.params.length - 1) {
          this.params.splice(index, 1);
          this.params.splice(index + 1, 0, row);
        }
      },
      // 删除参数项
      paramRemove(row, index) {
        this.params.splice(index, 1);
      },
      // 控件类型变化
      controlTypeChange() {
        if (this.currentColumn && this.currentColumn.objColumn) {
          if (this.data.controlType == 'DialogSelect' || this.data.controlType == 'MultiDialogSelect') {
            this.data.source = this.currentColumn.objColumn.dataType + 'Select';
          } else {
            this.data.source = this.currentColumn.objColumn.dataType;
          }
        }

        setTimeout(() => {
          this.$forceUpdate();
        });
      }
    }
  };
</script>
