<template>
  <div>
    <Modal
      ref="modal"
      v-model="opened"
      scrollable
      :mask-closable="layout.maskClosable"
      :draggable="layout.draggable"
      :sticky="true"
      :reset-drag-position="true"
      :width="(dataView && dataView.width ? dataView.width : 800) + 350"
    >
      <div slot="header">
        <slot name="header">
          <span class="title">{{ dataView.name }}</span>
          <span class="description">{{ dataView.description }}</span>
        </slot>
      </div>
      <div class="container">
        <div class="left">
          <Card :bordered="false" dis-hover class="toolbox">
            <Divider :plain="true" dashed class="title" size="small">{{ $t('Front_Label_Default_Column_Width') }}</Divider>
            <RadioGroup v-model="columnWidth" @on-change="columnWidthChange">
              <Radio label="Column12">{{ $t('Enum_ColumnWidth_Column12') }}</Radio>
              <Radio label="Column6">{{ $t('Enum_ColumnWidth_Column6') }}</Radio>
              <Radio label="Column4">{{ $t('Enum_ColumnWidth_Column4') }}</Radio>
              <Radio label="Column3">{{ $t('Enum_ColumnWidth_Column3') }}</Radio>
              <Radio label="Column2">{{ $t('Enum_ColumnWidth_Column2') }}</Radio>
            </RadioGroup>
            <template v-for="(componentGroup, index) in componentGroups">
              <Divider :key="'title' + index" :plain="true" dashed class="title" size="small">{{ componentGroup.name }}</Divider>
              <div :key="index" style="width: 100%; display: flex">
                <draggable
                  :animation="500"
                  v-model="componentGroup.components"
                  :scroll="true"
                  :group="{
                    name: 'sort',
                    pull: 'clone',
                    put: false
                  }"
                  :sort="false"
                  :clone="clone"
                  filter=""
                >
                  <template v-for="(component, index) in componentGroup.components">
                    <div :key="index" style="width: 50%; float: left">
                      <Button icon="md-list-box" @dblclick.native="dblclick(component)" class="component">{{ component.name }}</Button>
                    </div>
                  </template>
                </draggable>
              </div>
            </template>
          </Card>
        </div>
        <div class="right">
          <div class="ivu-ml-8 ivu-mr-8">
            <view-form-draggable ref="form" @edit="({ column, index }) => edit(column, index)" @remove="({ column, index }) => remove(column, index)" />
          </div>
        </div>
      </div>
      <div slot="footer">
        <Button type="primary" ghost custom-icon="fa fa-bars" @click="listMode">{{ $t('Front_Btn_List_Mode') }}</Button>
        <Button type="primary" v-if="!dataView.isVirtual" ghost custom-icon="fa fa-indent" @click="openColumnSelect">{{ $t('Front_Btn_Select_Column') }}</Button>
        <Button type="primary" custom-icon="fa fa-save" v-if="!isSetting" @click="save">{{ $t('Front_Btn_Save') }}</Button>
        <Button type="error" custom-icon="fa fa-save" v-if="isSetting" @click="globalSave">{{ $t('Front_Btn_Global_Save') }}</Button>
        <Button type="error" custom-icon="fa fa-cog" v-if="isSetting" @click="setting">{{ $t('Front_Btn_Form_Setting') }}</Button>
      </div>
    </Modal>
    <column-select ref="columnSelect" />
    <column-edit ref="columnEdit" view-type="FormView" />
    <modal-form ref="setting" view-code="FormViewSetting" v-if="isSetting">
      <template slot="footer">
        <Button type="primary" custom-icon="fa fa-save" @click="saveSetting">{{ $t('Front_Btn_Save') }}</Button>
      </template>
    </modal-form>
  </div>
</template>
<script>
  import { mapActions } from 'vuex';
  import mixinPage from '../../mixins/page';
  import columnEdit from './column-edit';
  import columnSelect from './column-select';
  import viewFormDraggable from './view-form-draggable';
  import draggable from 'vuedraggable';
  import enumApi from '../../api/enum';

  export default {
    mixins: [mixinPage],
    components: { columnEdit, columnSelect, viewFormDraggable, draggable },
    data() {
      return {
        columnWidth: 'Column6',
        opened: false,
        dataView: {},
        columns: [],
        componentGroups: []
      };
    },
    async created() {},
    props: {
      // 是否公共配置界面
      isSetting: {
        type: Boolean,
        default: false
      }
    },
    computed: {},
    methods: {
      ...mapActions('admin/dataView', {
        saveDataView: 'save',
        saveDataViewSetting: 'saveSetting'
      }),
      // 打开
      async open(dataView, columns) {
        this.dataView = dataView;
        this.columns = this.copy(columns);
        this.$refs.form.init(this.dataView, this.columns);
        this.opened = true;

        const res = await enumApi.query('ControlType');

        this.componentGroups = [
          {
            key: 'Normal',
            name: this.$t('Front_Label_Normal_Control'),
            components: []
          },
          {
            key: 'Datasource',
            name: this.$t('Front_Label_Data_Source_Control'),
            components: []
          },
          {
            key: 'DateTime',
            name: this.$t('Front_Label_Date_Time_Control'),
            components: []
          },
          {
            key: 'Other',
            name: this.$t('Front_Label_Other_Control'),
            components: []
          }
        ];

        res.forEach(item => {
          let component = {
            code: null,
            name: item.name,
            controlType: item.id,
            isShow: true,
            isVirtual: dataView.isVirtual,
            columnWidth: this.columnWidth,
            dataView
          };

          if (
            item.id == 'Label' ||
            item.id == 'TextInput' ||
            item.id == 'NumberInput' ||
            item.id == 'Check' ||
            item.id == 'Switch' ||
            item.id == 'Slider' ||
            item.id == 'TextArea'
          ) {
            this.componentGroups.find(componentGroup => componentGroup.key == 'Normal').components.push(component);
          } else if (
            item.id == 'Select' ||
            item.id == 'SelectWithOther' ||
            item.id == 'MultiSelect' ||
            item.id == 'ComboSelect' ||
            item.id == 'DialogSelect' ||
            item.id == 'MultiDialogSelect' ||
            item.id == 'AutoComplete' ||
            item.id == 'Radio' ||
            item.id == 'CheckGroup'
          ) {
            this.componentGroups.find(componentGroup => componentGroup.key == 'Datasource').components.push(component);
          } else if (item.id == 'Date' || item.id == 'Time' || item.id == 'DateTime' || item.id == 'Year' || item.id == 'YearMonth' || item.id == 'DateRange') {
            this.componentGroups.find(componentGroup => componentGroup.key == 'DateTime').components.push(component);
          } else if (
            item.id == 'Table' ||
            item.id == 'List' ||
            item.id == 'Attachment' ||
            item.id == 'Image' ||
            item.id == 'RichEditor' ||
            item.id == 'Placeholder' ||
            item.id == 'Custom'
          ) {
            this.componentGroups.find(componentGroup => componentGroup.key == 'Other').components.push(component);
          }
        });
      },
      // 关闭
      close() {
        this.opened = false;
      },
      // 打开字段设置界面
      edit(row, index) {
        this.$refs.columnEdit.open(row, index, this.columns, data => {
          let columns = this.$refs.form.columns;
          columns.splice(index, 1, data);
        });
      },
      // 移除
      remove(row, index) {
        this.confirm('Front_Msg_Sure_To_Remove_Control', async () => {
          let columns = this.$refs.form.columns;
          columns.splice(index, 1);
          this.$forceUpdate();
        });
      },
      // 打开字段选择界面
      openColumnSelect() {
        this.$refs.columnSelect.open(this.dataView, this.columns, checked => {
          // 移除未勾选的
          let columns = this.columns.filter(column => {
            return (
              checked.some(item => {
                return column.code === item.code;
              }) || column.isVirtual
            );
          });

          this.columns.splice(0, this.columns.length);
          columns.forEach(item => {
            this.columns.push(item);
          });

          // 添加新勾选的
          checked.forEach(item => {
            if (
              !this.columns.some(column => {
                return column.code === item.code;
              })
            ) {
              this.columns.push({
                code: item.code,
                name: item.name,
                dataType: item.dataType,
                dataView: this.dataView,
                isShow: true,
                controlType: this.getDefaultControlType(item.dataType),
                columnWidth: this.columnWidth, // 默认宽度1/2
                source: item.objColumn != null ? item.objColumn.dataType : null,
                sourceDataCode: item.objColumn != null ? 'id' : null,
                sourceModel: item.objColumn != null ? item.objColumn.dataType : null,
                sourceDisplayCode:
                  item.objColumn != null &&
                  item.objColumn.columns.some(function (column) {
                    return column.code === item.objColumn.code + '.name';
                  })
                    ? 'name'
                    : null
              });
            }
          });

          this.$forceUpdate();
        });
      },
      // 全局保存
      globalSave() {
        this.confirm('Front_Msg_Sure_To_Save_Global_Setting', () => {
          this.confirm('Front_Msg_Sure_To_Save_Global_Setting_Confirm', async () => {
            await this.saveDataView({
              code: this.dataView.code,
              columns: this.columns
            });

            this.$emit('on-change', this.dataView.code);
            this.success('Front_Msg_Success', () => {
              this.close();
            });
          });
        });
      },
      // 保存
      save() {
        this.confirm('Front_Msg_Sure_To_Save_Setting', async () => {
          await this.saveDataView({
            code: this.dataView.code,
            columns: this.columns
          });

          this.success('Front_Msg_Success', () => {
            this.close();
          });
        });
      },
      // 默认列宽变更
      columnWidthChange() {
        this.componentGroups.forEach(componentGroup => {
          componentGroup.components.forEach(component => {
            component.columnWidth = this.columnWidth;
          });
        });
      },
      // 拖动克隆
      clone(item) {
        return this.copy(item);
      },
      // 双击
      dblclick(item) {
        this.columns.push(this.copy(item));
      },
      // 设置
      setting() {
        this.$refs.setting.open(this.copy(this.dataView));
      },
      // 保存设置
      saveSetting() {
        this.confirm('Front_Msg_Sure_To_Save_Setting', async () => {
          let res = await this.saveDataViewSetting(this.$refs.setting.data);
          this.dataView = res.dataView;

          this.$emit('on-change', this.dataView.code);
          this.success('Front_Msg_Success', () => {
            this.$refs.setting.close();
          });
        });
      },
      // 切换至列表模式
      listMode() {
        this.$emit('list-mode', {
          dataView: this.dataView,
          columns: this.columns
        });
      },
      // 获取默认控件类型
      getDefaultControlType(dataType) {
        if (dataType == 'Integer' || dataType == 'BigInteger' || dataType == 'Decimal' || dataType == 'Float' || dataType == 'Double') {
          return 'NumberInput';
        } else if (dataType == 'Boolean') {
          return 'Check';
        } else if (dataType == 'DateTime') {
          return 'Date';
        } else {
          return 'TextInput';
        }
      }
    }
  };
</script>

<style scoped>
  .container {
    width: 100%;
    display: flex;
  }

  .container .left .toolbox {
    width: 350px;
    margin-right: 8px;
  }

  .container .left .toolbox .title {
    font-weight: bold;
  }

  .container .right {
    width: 100%;
  }

  .component {
    margin: 5px;
    width: 150px;
    text-align: left;
  }
</style>
