<template>
  <a-modal
    class="j-super-query-modal"
    style="top: 5%; max-height: 95%"
    :title="labels.advancedSearch"
    wrap-class-name="ant-modal-cust-warp"
    :mask="false"
    :visible="visible"
    :width="1000"
    @cancel="handleCancel"
  >
    <template slot="footer">
      <div style="float: left">
        <a-button :loading="loading" @click="handleReset"> {{ labels.reset }} </a-button>
        <a-button :loading="loading" @click="handleSave">
          {{ labels.saveQueryCondition }}
        </a-button>
      </div>
      <a-button :loading="loading" @click="handleCancel"> {{ labels.close }} </a-button>
      <a-button :loading="loading" type="primary" @click="handleOk"> {{ labels.query }} </a-button>
    </template>

    <a-spin :spinning="loading">
      <a-row>
        <a-col :sm="24" :md="24 - 5">
          <a-empty v-if="queryParamsModel.length === 0">
            <div slot="description">
              <span v-text="labels.noQueryConditions"></span>
              <a-divider type="vertical" />
              <a @click="handleAdd">{{ labels.clickToAdd }}</a>
            </div>
          </a-empty>

          <a-form v-else layout="inline">
            <a-form-item label="labels.matchFilter" style="margin-bottom: 12px">
              <a-select v-model="selectValue">
                <a-select-option value="AND"> {{ labels.andMAtchAllConditions }}</a-select-option>
                <a-select-option value="OR"> {{ labels.orMatchAnyCondition }}</a-select-option>
              </a-select>
            </a-form-item>
            <a-row
              style="margin-bottom: 10px"
              type="flex"
              :gutter="16"
              :key="index"
              v-for="(item, index) in queryParamsModel"
            >
              <a-col :span="8">
                <a-select
                  :placeholder="labels.queryField"
                  v-model="item.fieldCode"
                  @select="(val, option) => handleSelected(option, item)"
                >
                  <a-select-option
                    v-for="(f, fIndex) in fieldList"
                    :key="'field' + fIndex"
                    :data-idx="fIndex"
                    :data-itemid="f.id"
                    :value="f.fieldValue"
                  >
                    {{ f.text }}
                  </a-select-option>
                </a-select>
              </a-col>

              <a-col :span="4">
                <a-select :placeholder="labels.matchingRules" v-model="item.logicSymbol">
                  <a-select-option value="eq"> {{ labels.equals }} </a-select-option>
                  <a-select-option value="ne"> {{ labels.notEqualTo }} </a-select-option>
                  <a-select-option value="gt"> {{ labels.greaterThan }} </a-select-option>
                  <a-select-option value="ge"> {{ labels.greaterThanOrEqualTo }} </a-select-option>
                  <a-select-option value="lt"> {{ labels.lessThan }} </a-select-option>
                  <a-select-option value="le"> {{ labels.lessThanOrEqualTo }} </a-select-option>
                  <a-select-option value="left_like">
                    {{ labels.startWith3Points }}
                  </a-select-option>
                  <a-select-option value="right_like">
                    ${{ labels.endsWith3Points }}
                  </a-select-option>
                  <a-select-option value="like"> {{ labels.includes }} </a-select-option>
                  <a-select-option value="in"> {{ labels.in3Points }} </a-select-option>
                </a-select>
              </a-col>
              <a-col :span="8">
                <template v-if="item.dictCode">
                  <template v-if="item.fieldType === 'table-dict'">
                    <j-popup
                      v-model="item.fieldValue"
                      :code="item.dictTable"
                      :dest-fields="item.dictCode"
                      :field="item.dictCode"
                      :org-fields="item.dictCode"
                    />
                  </template>
                  <j-dict-select-tag
                    :placeholder="labels.pleaseSelectValue"
                    v-else
                    v-model="item.fieldValue"
                    :dict-code="item.dictCode"
                  />
                </template>
                <j-select-multi-user
                  :placeholder="labels.pleaseSelectUser"
                  v-else-if="item.fieldType === 'select-user'"
                  v-model="item.fieldValue"
                  :buttons="false"
                  :multiple="false"
                  :return-keys="['id', item.customReturnField || 'username']"
                />
                <j-select-depart
                  :placeholder="labels.pleaseSelectDepartment"
                  v-else-if="item.fieldType === 'select-depart'"
                  v-model="item.fieldValue"
                  :custom-return-field="item.customReturnField || 'id'"
                  :multi="false"
                />
                <j-date
                  :placeholder="labels.pleaseSelectDate"
                  style="width: 100%"
                  v-else-if="item.fieldType == 'date'"
                  v-model="item.fieldValue"
                />
                <j-date
                  date-format="YYYY-MM-DD HH:mm:ss"
                  :placeholder="labels.pleaseSelectTime"
                  style="width: 100%"
                  v-else-if="item.fieldType == 'datetime'"
                  v-model="item.fieldValue"
                  :show-time="true"
                />
                <a-input-number
                  :placeholder="labels.pleaseEnterNumber"
                  style="width: 100%"
                  v-else-if="item.fieldType == 'int' || item.fieldType == 'number'"
                  v-model="item.fieldValue"
                />
                <a-input v-else v-model="item.fieldValue" placeholder="labels.pleaseEnterValue" />
              </a-col>
              <a-col :span="4">
                <a-button @click="handleAdd" icon="plus" />&nbsp;
                <a-button @click="handleDel(index)" icon="minus" />
              </a-col>
            </a-row>
          </a-form>
        </a-col>
        <a-col :sm="24" :md="5">
          <!-- 查询记录 -->

          <a-card class="j-super-query-history-card" :bordered="true">
            <div slot="title" v-text="labels.queryToBeSaved"></div>

            <a-empty
              class="j-super-query-history-empty"
              :description="labels.noQuiresSaved"
              v-if="treeData.length === 0"
            />
            <a-tree
              class="j-super-query-history-tree"
              show-icon
              v-else
              :selectedKeys="selectedKeys"
              :tree-data="treeData"
              @rightClick="handleTreeRightClick"
              @select="handleTreeSelect"
            />
          </a-card>
        </a-col>
      </a-row>
    </a-spin>

    <a-modal
      :title="labels.pleaseEnterNameToSave"
      :visible="prompt.visible"
      @cancel="prompt.visible = false"
      @ok="handlePromptOk"
    >
      <a-input v-model="prompt.value" />
    </a-modal>
  </a-modal>
</template>

<script>
import { ft } from '../../../lib/utils';

const LABELS = {
  add: ft('i18n_common_add', '添加'),
  advancedSearch: ft('i18n_common_advanced_search', '高级查询'),
  antdvVersionNoSupport: ft('i18n_common_antdv_version_not_support', 'Ant design vue 版本不支持'),
  clickTo: ft('i18n_common_click_to', '点击'),
  close: ft('i18n_common_close', '关闭'),
  conditionIsEmpty: ft('i18n_common_condition_is_empty', '条件为空'),
  data: ft('i18n_common_add', '添加'),
  date: ft('i18n_common_date', '日期'),
  department: ft('i18n_common_department', '部门'),
  endsWith3Points: ft('i18n_common_ends_with_three_points', '以...结束'),
  equals: ft('i18n_common_equals', '等于'),
  failedToSave: ft('i18n_common_failed_to_save', '保存失败'),
  greaterThan: ft('i18n_common_greater_than', '大于'),
  greaterThanOrEqualTo: ft('i18n_common_greater_than_or_equal_to', '大于等于'),
  includes: ft('i18n_common_includes', '包含'),
  in3Points: ft('i18n_common_in_three_points', '在...中'),
  lessThan: ft('i18n_common_less_than', '小于'),
  lessThanOrEqualTo: ft('i18n_common_less_than_or_equal_to', '小于等于'),
  matchAllConditions: ft('i18n_common_match_all_conditions', '匹配所有条件'),
  matchAnyCondition: ft('i18n_common_match_any_condition', '匹配的任意条件'),
  matchFilter: ft('i18n_common_match_filter', '匹配过滤条件'),
  matchingRules: ft('i18n_common_matching_rules', '匹配规则'),
  nameToSave: ft('i18n_common_name_to_saved', '保存的名称'),
  noQueryConditions: ft('i18n_common_no_query_conditions', '没有查询条件'),
  noQuiresSaved: ft('i18n_common_no_queries_saved', '没有保存任何查询'),
  notEqualTo: ft('i18n_common_not_equal_to', '不等于'),
  number: ft('i18n_common_number', '数值'),
  orderNumber: ft('i18n_common_order_number', '订单编号'),
  pleaseEnter: ft('i18n_common_please_enter', '请输入 '),
  pleaseSelect: ft('i18n_common_please_select', '请选择 '),
  query: ft('i18n_common_query', '查询'),
  queryField: ft('i18n_common_query_field', '查询字段'),
  queryToBeSaved: ft('i18n_common_query_to_be_saved', '将要保存的查询'),
  reset: ft('i18n_common_reset', '重置'),
  saveNameIsEmpty: ft('i18n_common_save_name_is_empty', '保存名称为空'),
  startWith3Points: ft('i18n_common_start_with_three_points', '以?开始'),
  time: ft('i18n_common_datetime', '时间'),
  user: ft('i18n_common_user', '用户'),
  value: ft('i18n_common_value', '值'),
  whetherToDeleteCurrentQuery: ft(
    'i18n_common_whether_to_delete_the_current_query',
    '是否删除当前查询?'
  )
};

LABELS.clickToAdd = `${LABELS.clickTo}${LABELS.add.toLowerCase()}`;
LABELS.andMAtchAllConditions = `AND[${LABELS.matchAllConditions}]`;
LABELS.orMatchAnyCondition = `${LABELS.matchAnyCondition}`;
LABELS.pleaseEnterNameToSave = `${LABELS.pleaseEnter}${LABELS.nameToSave}`;
LABELS.pleaseEnterNumber = `${LABELS.pleaseEnter}${LABELS.number}`;
LABELS.pleaseEnterValue = `${LABELS.pleaseEnter}${LABELS.value}`;
LABELS.pleaseSelectDate = `${LABELS.pleaseSelect}${LABELS.date}`;
LABELS.pleaseSelectDepartment = `${LABELS.pleaseSelect}${LABELS.department}`;
LABELS.pleaseSelectTime = `${LABELS.pleaseSelect}${LABELS.time}`;
LABELS.pleaseSelectUser = `${LABELS.pleaseSelect}${LABELS.user}`;
LABELS.pleaseSelectValue = `${LABELS.pleaseSelect}${LABELS.value}`;

export default {
  name: 'SuperQuery',
  props: {
    tableCode: {
      type: String,
      default: ''
    },
    callback: {
      type: String,
      required: false,
      default: 'handleSuperQuery'
    },
    saveCode: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      labels: LABELS,
      prompt: {
        visible: false,
        value: ''
      },
      visible: false,
      loading: false,
      fieldList: [],
      queryParamsModel: [{ fieldCode: LABELS.orderNumber, fieldValue: 'PO2021040700004' }],
      treeIcon: <a-icon type="file-text" />,
      treeData: [],
      selectValue: 'AND',
      selectedKeys: []
    };
  },
  computed: {
    izMobile() {
      return this.device === 'mobile';
    },
    tooltipProps() {
      return this.izMobile ? { visible: false } : {};
    },
    fullSaveCode() {
      let saveCode = this.saveCode;
      if (saveCode == null || saveCode === '') {
        saveCode = this.$route.fullPath;
      }
      return this.saveCodeBefore + saveCode;
    }
  },
  watch: {
    // 当 saveCode 变化时，重新查询已保存的条件
    fullSaveCode: {
      immediate: true,
      handler() {
        if (this.$ls && this.$ls.get && typeof this.$ls.get === 'function') {
          const list = this.$ls.get(this.fullSaveCode);
          if (list instanceof Array) {
            this.saveTreeData = list.map((i) => this.renderSaveTreeData(i));
          }
        }
      }
    }
  },
  methods: {
    close() {
      this.$emit('close');
      this.visible = false;
    },

    confirmRemoveTreeItem(event, vNode) {
      event.stopPropagation();

      const _this = this;

      this.$confirm({
        content: LABELS.whetherToDeleteCurrentQuery,
        onOk: () => {
          const { eventKey } = vNode;
          // _this.treeData.splice(Number.parseInt(eventKey.substring(2)), 1)
          _this.deleteQueryCondition(vNode.id, Number.parseInt(eventKey.substring(2)));
          // _this.saveToLocalStore()
        }
      });
    },

    handleAdd() {
      this.queryParamsModel.push({});
    },

    handleCancel() {
      this.close();
    },

    handleDel(index) {
      this.queryParamsModel.splice(index, 1);
    },

    handleOk() {
      this.$emit(this.callback, this.queryParamsModel, this.selectValue);

      /*
      if (!this.isNullArray(this.queryParamsModel)) {
        // let params = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel))
        const params = this.removeEmptyObject(this.queryParamsModel);

        for (const param of params) {
          param.joiner = this.selectValue;
        }

        this.$emit(this.callback, params, this.selectValue);
      } else {
        this.$emit(this.callback, null, null);
      }
      */
    },

    handlePromptOk() {
      const { value } = this.prompt;

      if (value) {
        this.saveQueryCondition();
      } else {
        this.$message.warning(`${LABELS.failedToSave}: ${LABELS.saveNameIsEmpty}`);
      }
    },

    handleReset() {
      this.queryParamsModel = [{}];
      this.handleOk();
    },

    handleSave() {
      // const queryParams = this.removeEmptyObject(utils.cloneObject(this.queryParamsModel));
      const queryParams = this.removeEmptyObject(this.queryParamsModel);
      if (this.isNullArray(queryParams)) {
        this.$message.warning(`${LABELS.failedToSave}: ${LABELS.conditionIsEmpty}`);
      } else {
        this.prompt.value = '';
        this.prompt.visible = true;
      }
    },

    handleSelected(option, item) {
      const index = option.data.attrs['data-idx'];
      const itemId = option.data.attrs['data-itemid'];
      const { fieldType, dictCode, dictTable, customReturnField } = this.fieldList[index];

      item.fieldType = fieldType;
      item.dictCode = dictCode;
      item.dictTable = dictTable;
      item.customReturnField = customReturnField;
      item.queryItemId = itemId;

      this.$set(item, 'fieldValue', '');
    },

    handleTreeSelect(idx, event) {
      if (event.selectedNodes[0]) {
        this.selectedKeys = idx;
        this.requestQueryItem(event.selectedNodes[0].data.props.id);
      }
    },

    isNullArray(array) {
      // 判断是不是空数组对象
      if (!array || array.length === 0) {
        return true;
      }

      if (array.length === 1) {
        const obj = array[0];
        if (!obj.fieldCode || !obj.fieldValue || !obj.logicSymbol) {
          return true;
        }
      }
      return false;
    },

    // 去掉数组中的空对象
    removeEmptyObject(array) {
      for (let i = 0; i < array.length; i++) {
        const item = array[i];
        if (item == null || Object.keys(item).length < 1) {
          array.splice(i--, 1);
        }
      }

      return array;
    },

    /**
     * 渲染保存查询条件的 title（加个删除按钮）
     */
    renderSaveTreeData(item) {
      item.icon = this.treeIcon;
      item.originTitle = item.title;
      item.title = (arg1, arg2) => {
        let vNode;
        // 兼容旧版的 ant design vue
        if (arg1.dataRef) {
          vNode = arg1;
        } else if (arg2.dataRef) {
          vNode = arg2;
        } else {
          return `<span style="color:red;">${LABELS.antdvVersionNoSupport}</span>`;
        }

        const { originTitle } = vNode.dataRef;

        return (
          <div class="j-history-tree-title">
            <span>{originTitle}</span>

            <div
              class="j-history-tree-title-closer"
              onClick={(e) => this.confirmRemoveTreeItem(e, vNode)}
            >
              <a-icon type="close-circle" />
            </div>
          </div>
        );
      };
      return item;
    },

    show() {
      if (!this.queryParamsModel || this.queryParamsModel.length === 0) {
        this.queryParamsModel = [{}];
      }
      // this.requestFieldList();
      // this.requestQueryHeader();
      this.visible = true;
    }
  }
};
</script>

<style lang="scss" scoped>
.j-super-query-modal {
  .j-super-query-history-card /deep/ {
    .ant-card-body,
    .ant-card-head-title {
      padding: 0;
    }

    .ant-card-head {
      padding: 4px 8px;
      min-height: initial;
    }
  }

  .j-super-query-history-empty /deep/ {
    .ant-empty-image {
      height: 80px;
      line-height: 80px;
      margin-bottom: 0;
    }

    img {
      width: 80px;
      height: 65px;
    }

    .ant-empty-description {
      color: #afafaf;
      margin: 8px 0;
    }
  }

  // .j-super-query-history-tree /deep/ {
  //   .ant-tree-switcher {
  //     display: none;
  //   }

  //   .ant-tree-node-content-wrapper {
  //     width: 100%;
  //   }
  // }

  .j-super-query-history-tree {
    .j-history-tree-title {
      width: calc(100% - 24px);
      position: relative;
      display: inline-block;

      &-closer {
        color: #999999;
        position: absolute;
        top: 0;
        right: 0;
        width: 24px;
        height: 24px;
        text-align: center;
        opacity: 0;
        transition: opacity 0.3s, color 0.3s;

        &:hover {
          color: #666666;
        }

        &:active {
          color: #333333;
        }
      }

      &:hover {
        .j-history-tree-title-closer {
          opacity: 1;
        }
      }
    }

    /deep/ .ant-tree-switcher {
      display: none;
    }

    /deep/ .ant-tree-node-content-wrapper {
      width: 100%;
    }
  }
}
</style>
