<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">{{ $t('Front_Label_Property_Setting') }}</span>
        <span class="description">{{ $t('Front_Label_Property_Setting_Desc') }}</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">
              <FormItem :label="$t('Front_Label_Property_Name')" prop="propertyName">
                <Input type="text" v-model="data.propertyName"></Input>
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem :label="$t('Front_Label_Property_Code')" prop="propertyCode">
                <Input type="text" v-model="data.propertyCode"></Input>
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem :label="$t('Front_Label_Data_Type')" 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">
              <FormItem :label="$t('Front_Label_Control_Type')" prop="controlType">
                <Select v-model="data.controlType" :transfer="true">
                  <Option key="TextInput" value="TextInput">单行文本框</Option>
                  <Option key="NumberInput" value="NumberInput">数字输入框</Option>
                  <Option key="Check" value="Check">勾选</Option>
                  <Option key="Select" value="Select">选择框</Option>
                  <Option key="MultiSelect" value="MultiSelect">多选选择框</Option>
                  <Option key="DialogSelect" value="DialogSelect">弹出选择框</Option>
                  <Option key="MultiDialogSelect" value="MultiDialogSelect">多选弹出选择框</Option>
                </Select>
              </FormItem>
            </Col>
            <Col v-bind="grid8" v-if="needDataSource" v-show="data.controlType == 'Select' || data.controlType == 'MultiSelect' || data.controlType == 'ComboSelect'">
              <FormItem :label="$t('Front_Label_Data_Source')" 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="needDataSource" v-show="data.controlType == 'DialogSelect' || data.controlType == 'MultiDialogSelect'">
              <FormItem :label="$t('Front_Label_View')" key="DataViewSource" prop="DataViewSource">
                <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">
              <FormItem :label="$t('Front_Label_Source_Data_Code')" key="SourceDataCode" prop="SourceDataCode" v-if="data.source">
                <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="needDataSource">
              <FormItem :label="$t('Front_Label_Source_Display_Code')" key="SourceDisplayCode" prop="SourceDisplayCode" v-if="data.source">
                <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="needDataSource">
              <FormItem :label="$t('Front_Label_Param')" key="Param" prop="Param" v-if="data.source">
                <Input type="text" @click.native="paramOpen" :readonly="true" v-model="data.param" maxlength="200" />
              </FormItem>
            </Col>
            <Col v-bind="grid8">
              <FormItem :label="$t('Front_Label_Is_Required')" key="isRequired" prop="isRequired">
                <Switch
                  :value="!!data.isRequired"
                  @input="
                    $event => {
                      data.isRequired = $event;
                    }
                  "
                />
              </FormItem>
            </Col>
          </Row>
        </Form>
      </div>
      <div slot="footer">
        <Button type="primary" custom-icon="fa fa-check" @click="save">{{ $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">{{ $t('Front_Label_Param') }}</span>
          <span class="description">{{ $t('Front_Label_Param_Desc') }}</span>
        </slot>
      </div>
      <div class="i-table-no-border">
        <Table :columns="parpamColumns" :data="params" stripe size="small" no-data-text="暂无数据...">
          <template slot-scope="{ row, index }" slot="command">
            <Button size="small" :title="$t('Front_Btn_Edit')" type="primary" ghost custom-icon="fa fa-edit" @click="paramEdit(row, index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Up')" type="primary" ghost custom-icon="fa fa-chevron-up" @click="upParam(row, index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Down')" type="primary" ghost custom-icon="fa fa-chevron-down" @click="downParam(row, index)"></Button>
            <Button size="small" :title="$t('Front_Btn_Remove')" type="primary" ghost custom-icon="fa fa-times" @click="paramRemove(row, 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">{{ $t('Front_Label_Param_Setting') }}</span>
        <span class="description">{{ $t('Front_Label_Param_Setting_Desc') }}</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="$t('Front_Msg_Column')" 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="$t('Front_Msg_Value')" key="val" prop="val">
                <Input type="text" v-model="paramData.val" />
              </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 columnCheck from '../../components/view/column-check';
  import mixinPage from '../../mixins/page';
  import modelApi from '../../api/model';

  export default {
    mixins: [mixinPage],
    components: { columnCheck },
    data() {
      return {
        data: {},
        callback: null,
        opened: false,
        params: [],
        paramData: {},
        paramOpened: false,
        paramItemOpened: false,
        sourceBefore: null
      };
    },
    async created() {},
    props: {},
    computed: {
      // 选择框，或复选框组，且非枚举类型，需要输入数据源
      needDataSource() {
        if (this.data) {
          return (
            (this.data.controlType === 'Select' ||
              this.data.controlType === 'MultiSelect' ||
              this.data.controlType === 'DialogSelect' ||
              this.data.controlType === 'MultiDialogSelect') &&
            (this.data.dataType == null || this.data.dataType.indexOf('Enum:') !== 0)
          );
        } else {
          return false;
        }
      },
      rules() {
        return {
          propertyName: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          propertyCode: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          dataType: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          controlType: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          source: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          sourceDataCode: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          },
          sourceDisplayCode: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur'
          }
        };
      },
      parpamColumns() {
        return [
          { title: this.$t('Front_Label_Param'), resizable: true, align: 'center', key: 'code' },
          { title: this.$t('Front_Label_Value'), align: 'center', resizable: true, key: 'val' },
          { slot: 'command', title: ' ', align: 'center', resizable: true, fixed: 'right' }
        ];
      },
      paramItemFormRules() {
        return {
          code: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur,change'
          },
          val: {
            type: 'string',
            required: true,
            message: this.$t('Front_Msg_Please_Input'),
            trigger: 'blur,change'
          }
        };
      }
    },
    methods: {
      // 打开
      open(row, callback) {
        if (row) {
          this.data = this.copy(row);
        } else {
          this.data = {};
        }

        this.callback = callback;
        this.opened = true;

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

        if (!isOK) {
          this.error('Front_Msg_Form_Validate_Fail');
        } else {
          this.confirm('Front_Msg_Sure_To_Save', async () => {
            if (!this.data.id) {
              await modelApi.add('RoleProperty', this.data);
            } else {
              await modelApi.update('RoleProperty', this.data);
            }

            this.success('Front_Msg_Success');
            this.callback();
            this.opened = false;
          });
        }
      },
      // 打开字段选择界面
      openSelect() {
        this.$refs.columnCheck.open(this.dataView.model, checked => {
          this.data.code = checked.code;
          this.data.name = checked.name;
          this.data.dataType = checked.dataType;
          this.data.source = checked.objColumn != null ? checked.objColumn.dataType : null;
          this.data.sourceDataCode = checked.objColumn != null ? 'id' : null;
          this.data.sourceDisplayCode =
            checked.objColumn != null &&
            checked.objColumn.columns.some(function (column) {
              return column.code === checked.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;
        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) {
            this.params.push({
              code: key,
              val: obj[key]
            });
          }
        }
      },
      // 参数框确认
      async paramItemSave() {
        let isOK = await this.$refs.paramItemForm.validate();

        if (!isOK) {
          this.error('Front_Msg_Form_Validate_Fail');
          return;
        }
        let val = this.paramData.val;
        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;
        } else {
          this.params.push({
            code: this.paramData.code,
            val: val
          });
        }
        this.paramItemOpened = false;
        this.$refs.paramItemForm.resetFields();
      },
      paramItemClose() {
        this.paramItemOpened = false;
        this.$refs.paramItemForm.resetFields();
      },
      // 打开字段选择界面
      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(']', ''),
            source: row
          };
        } else {
          this.paramData = {
            code: '',
            val: ''
          };
        }
        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);
      }
    }
  };
</script>
