<template>
  <el-row class="region-page">
    <el-col class="region-page__tree-panel" :span="6">
      <div class="box">
        <el-scrollbar>
          <basic-container>
            <avue-tree :option="treeOption" :data="treeData" @node-click="nodeClick" />
          </basic-container>
        </el-scrollbar>
      </div>
    </el-col>
    <el-col class="region-page__form-panel" :span="18">
      <basic-container>
        <el-form class="region-page__search" :model="searchForm" inline>
          <el-form-item label="区域编码">
            <el-input v-model="searchForm.code" clearable placeholder="请输入区域编码" />
          </el-form-item>
          <el-form-item label="区域名称">
            <el-input v-model="searchForm.name" clearable placeholder="请输入区域名称" />
          </el-form-item>
          <el-form-item label="区域层级">
            <el-select v-model="searchForm.regionLevel" clearable placeholder="请选择区域层级">
              <el-option label="省份" :value="1" />
              <el-option label="省市" :value="2" />
              <el-option label="区县" :value="3" />
            </el-select>
          </el-form-item>
          <el-form-item label="数据来源">
            <el-select v-model="searchForm.dataSource" clearable placeholder="请选择数据来源">
              <el-option label="手动录入" value="手动录入" />
              <el-option label="初始化导入" value="初始化导入" />
            </el-select>
          </el-form-item>
          <el-form-item label="启停状态">
            <el-select v-model="searchForm.status" clearable placeholder="请选择启停状态">
              <el-option label="启用" :value="1" />
              <el-option label="停用" :value="2" />
            </el-select>
          </el-form-item>
          <el-form-item class="region-page__search-actions">
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleSearchReset">清空</el-button>
          </el-form-item>
        </el-form>
        <el-button-group>
          <el-button
            v-if="permission.region_add"
            type="primary"
            icon="el-icon-plus"
            @click="addCountry"
            >新增国家
          </el-button>
          <el-button
            v-if="permission.region_add"
            type="primary"
            icon="el-icon-plus"
            @click="addChildren"
            >新增下级
          </el-button>
          <el-button
            v-if="permission.region_delete"
            type="primary"
            icon="el-icon-delete"
            @click="handleDelete"
            >删除
          </el-button>
          <el-button
            v-if="permission.region_import"
            type="primary"
            icon="el-icon-upload"
            @click="handleImport"
            >导入
          </el-button>
          <el-button
            v-if="permission.region_export"
            type="primary"
            icon="el-icon-download"
            @click="handleExport"
            >导出
          </el-button>
          <el-button
            v-if="permission.region_sync"
            type="primary"
            icon="el-icon-refresh"
            :loading="syncLoading"
            @click="handleSync"
            >同步
          </el-button>
          <!--          <el-button-->
          <!--            v-if="permission.region_debug"-->
          <!--            type="primary"-->
          <!--            icon="el-icon-video-play"-->
          <!--            @click="handleDebug"-->
          <!--            >调试-->
          <!--          </el-button>-->
        </el-button-group>
      </basic-container>
      <basic-container>
        <avue-form ref="form" :option="regionOption" v-model="regionForm" @submit="handleSubmit">
          <template #parentName="{}">
            <el-select
              class="region-parent-select"
              v-model="regionForm.parentCode"
              filterable
              :disabled="isCountryRegion"
              placeholder="请选择父区划"
              @change="handleParentChange"
            >
              <el-option
                v-for="item in parentOptions"
                :key="item.code"
                :label="item.name"
                :value="item.code"
              />
            </el-select>
          </template>
          <template #code="{}">
            <el-input
              v-if="isCountryRegion"
              placeholder="请输入国家编码，如 +86"
              v-model="regionForm.code"
            />
            <el-input
              v-else-if="isProvinceRegion"
              placeholder="请输入省级区划编号"
              v-model="regionForm.subCode"
            />
            <el-input v-else placeholder="请输入 区划子编号" v-model="regionForm.subCode">
              <template #prepend>{{ regionForm.parentCode }}</template>
            </el-input>
          </template>
        </avue-form>
        <el-dialog title="行政区划数据导入" append-to-body v-model="excelBox" width="555px">
          <avue-form :option="excelOption" v-model="excelForm">
            <template #excelTemplate>
              <el-button type="primary" @click="handleTemplate">
                点击下载<i class="el-icon-download el-icon--right"></i>
              </el-button>
            </template>
          </avue-form>
        </el-dialog>
        <el-dialog title="行政区划数据调试" append-to-body v-model="debugBox" width="350px">
          <avue-form :option="debugOption" v-model="debugForm" />
        </el-dialog>
      </basic-container>
    </el-col>
  </el-row>
</template>

<script>
import { getLazyTree, getDetail, submit, remove, sync } from '@/api/base/region';
import { exportBlob } from '@/api/common';
import { mapGetters } from 'vuex';
import { validatenull } from '@/utils/validate';
import { downloadXls } from '@/utils/util';
import { openImportDialog } from '@/utils/import-excel';
import { getToken } from '@/utils/auth';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

const ROOT_PARENT_CODE = '0';

export default {
  data() {
    return {
      topCode: ROOT_PARENT_CODE,
      treeCode: '',
      treeParentCode: '',
      treeData: [],
      searchForm: {
        code: '',
        name: '',
        regionLevel: undefined,
        dataSource: '',
        status: undefined,
      },
      parentOptions: [],
      syncLoading: false,
      treeOption: {
        nodeKey: 'id',
        lazy: true,
        treeLoad: (node, resolve) => {
          const parentCode = node.level === 0 ? ROOT_PARENT_CODE : node.data.id;
          getLazyTree(parentCode, this.searchForm).then(res => {
            resolve(
              res.data.data.map(item => {
                return {
                  ...item,
                  leaf: !item.hasChildren,
                };
              })
            );
          });
        },
        addBtn: false,
        menu: false,
        size: 'default',
        props: {
          labelText: '标题',
          label: 'title',
          value: 'value',
          children: 'children',
        },
      },
      regionForm: {},
      regionOption: {
        labelWidth: 'auto',
        column: [
          {
            label: '父区划编号',
            prop: 'parentCode',
            span: 24,
            display: false,
            rules: [
              {
                required: true,
                message: '请输入父区划编号',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '父区划名称',
            prop: 'parentName',
            span: 24,
            formslot: true,
          },
          {
            label: '区划编号',
            prop: 'code',
            formslot: true,
            span: 24,
            rules: [
              {
                required: true,
                message: '请输入区划编号',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '区划子编号',
            prop: 'subCode',
            display: false,
          },
          {
            label: '区划名称',
            prop: 'name',
            span: 24,
            rules: [
              {
                required: true,
                message: '请输入区划名称',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '区划等级',
            prop: 'regionLevel',
            type: 'radio',
            dicUrl: '/blade-system/dict/dictionary?code=region',
            props: {
              label: 'dictValue',
              value: 'dictKey',
            },
            dataType: 'number',
            span: 24,
            rules: [
              {
                required: true,
                message: '请选择区划等级',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '区划排序',
            prop: 'sort',
            type: 'number',
            span: 24,
            rules: [
              {
                required: true,
                message: '请输入区划排序',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '区划备注',
            prop: 'remark',
            type: 'textarea',
            minRows: 6,
            span: 24,
          },
        ],
      },
      excelBox: false,
      excelForm: {},
      excelOption: {
        submitBtn: false,
        emptyBtn: false,
        column: [
          {
            label: '模板上传',
            prop: 'excelFile',
            type: 'upload',
            drag: true,
            loadText: '模板上传中，请稍等',
            span: 24,
            propsHttp: {
              res: 'data',
            },
            tip: '请上传 .xls,.xlsx 标准格式文件',
            action: '/blade-system/region/import-region',
          },
          {
            label: '数据覆盖',
            prop: 'isCovered',
            type: 'switch',
            align: 'center',
            width: 80,
            dicData: [
              {
                label: '否',
                value: 0,
              },
              {
                label: '是',
                value: 1,
              },
            ],
            value: 0,
            slot: true,
            rules: [
              {
                required: true,
                message: '请选择是否覆盖',
                trigger: 'blur',
              },
            ],
          },
          {
            label: '模板下载',
            prop: 'excelTemplate',
            formslot: true,
            span: 24,
          },
        ],
      },
      debugBox: false,
      debugForm: {},
      debugOption: {
        labelWidth: 'auto',
        submitBtn: false,
        emptyBtn: false,
        column: [
          {
            label: '省份',
            prop: 'province',
            type: 'select',
            props: {
              label: 'name',
              value: 'code',
            },
            cascader: ['city'],
            dicUrl: '/blade-system/region/select',
            span: 24,
          },
          {
            label: '地市',
            prop: 'city',
            type: 'select',
            props: {
              label: 'name',
              value: 'code',
            },
            cascader: ['district'],
            dicFlag: false,
            dicUrl: '/blade-system/region/select?code={{province}}',
            span: 24,
          },
          {
            label: '区县',
            prop: 'district',
            type: 'select',
            props: {
              label: 'name',
              value: 'code',
            },
            dicFlag: false,
            dicUrl: '/blade-system/region/select?code={{city}}',
            span: 24,
          },
        ],
      },
    };
  },
  watch: {
    'regionForm.subCode'() {
      if (this.isCountryRegion) {
        return;
      }
      this.syncRegionCode();
    },
    'excelForm.isCovered'() {
      this.syncImportAction();
    },
  },
  computed: {
    ...mapGetters(['permission']),
    isCountryRegion() {
      return (
        Number(this.regionForm.regionLevel) === 0 || this.regionForm.parentCode === this.topCode
      );
    },
    isProvinceRegion() {
      return Number(this.regionForm.regionLevel) === 1;
    },
    isEditRegion() {
      return !validatenull(this.regionForm.originalCode);
    },
    permissionList() {
      return {
        addBtn: this.validData(this.permission.region_add, false),
        viewBtn: this.validData(this.permission.region_view, false),
        delBtn: this.validData(this.permission.region_delete, false),
        editBtn: this.validData(this.permission.region_edit, false),
      };
    },
    ids() {
      let ids = [];
      this.selectionList.forEach(ele => {
        ids.push(ele.id);
      });
      return ids.join(',');
    },
  },
  methods: {
    initTree() {
      this.treeData = [];
      getLazyTree(this.topCode, this.searchForm).then(res => {
        this.treeData = res.data.data.map(item => {
          return {
            ...item,
            leaf: !item.hasChildren,
          };
        });
      });
    },
    handleSearch() {
      this.initTree();
      this.regionForm = {};
    },
    handleSearchReset() {
      this.searchForm = {
        code: '',
        name: '',
        regionLevel: undefined,
        dataSource: '',
        status: undefined,
      };
      this.handleSearch();
    },
    nodeClick(data) {
      this.setRegionColumnDisplay('code', true);
      this.treeCode = data.id;
      this.treeParentCode = data.parentId;
      getDetail(this.treeCode).then(res => {
        this.regionForm = res.data.data;
        this.regionForm.originalCode = this.regionForm.code;
        this.regionForm.subCode =
          this.regionForm.parentCode === this.topCode
            ? this.regionForm.code
            : this.regionForm.code.replace(this.regionForm.parentCode, '');
        this.loadParentOptions(this.regionForm.parentCode, this.regionForm.parentName);
      });
    },
    addCountry() {
      this.setRegionColumnDisplay('code', true);
      this.treeCode = '';
      this.treeParentCode = this.topCode;
      this.parentOptions = this.getRootParentOptions();
      this.regionForm = {
        parentCode: this.topCode,
        parentName: '根节点',
        code: '',
        subCode: '',
        originalCode: '',
        name: '',
        regionLevel: 0,
        sort: 1,
      };
    },
    addChildren() {
      if (validatenull(this.regionForm.code) || validatenull(this.regionForm.name)) {
        this.$message.warning('请先选择一项区划');
        return;
      }
      const parentCode = this.regionForm.code;
      const parentName = this.regionForm.name;
      const parentGroupCode = this.regionForm.parentCode || this.topCode;
      this.setRegionColumnDisplay('code', true);
      this.regionForm.parentCode = parentCode;
      this.regionForm.parentName = parentName;
      this.regionForm.code = '';
      this.regionForm.subCode = '';
      this.regionForm.originalCode = '';
      this.regionForm.name = '';
      this.regionForm.regionLevel =
        this.regionForm.regionLevel === 5 ? 5 : this.regionForm.regionLevel + 1;
      this.loadParentOptionsByGroup(parentGroupCode, parentCode, parentName);
    },
    setRegionColumnDisplay(prop, display) {
      const column = this.findColumn(this.regionOption.column, prop);
      if (column) {
        column.display = display;
      }
    },
    handleParentChange(value) {
      const parent = this.parentOptions.find(item => item.code === value);
      this.regionForm.parentName = parent ? parent.name : '';
      this.syncRegionCode();
    },
    syncRegionCode() {
      if (this.isCountryRegion) {
        return;
      }
      const parentCode = this.isProvinceRegion ? '' : this.regionForm.parentCode || '';
      this.regionForm.code = parentCode + (this.regionForm.subCode || '');
    },
    getRootParentOptions() {
      return [
        {
          code: this.topCode,
          name: '根节点',
        },
      ];
    },
    normalizeParentOption(region) {
      return {
        code: String(region.code || region.id || ''),
        name: region.name || region.title || '',
      };
    },
    ensureSelectedParent(options, selectedCode, selectedName) {
      if (validatenull(selectedCode) || options.some(item => item.code === selectedCode)) {
        return options;
      }
      return [
        ...options,
        {
          code: String(selectedCode),
          name: selectedName || selectedCode,
        },
      ];
    },
    loadParentOptions(selectedCode, selectedName) {
      if (validatenull(selectedCode) || selectedCode === this.topCode) {
        this.parentOptions = this.getRootParentOptions();
        return;
      }
      getDetail(selectedCode).then(res => {
        const parent = res.data.data || {};
        const groupCode = parent.parentCode || this.topCode;
        this.loadParentOptionsByGroup(groupCode, selectedCode, selectedName);
      });
    },
    loadParentOptionsByGroup(groupCode, selectedCode, selectedName) {
      if (validatenull(groupCode)) {
        this.parentOptions = this.ensureSelectedParent([], selectedCode, selectedName);
        return;
      }
      getLazyTree(groupCode).then(res => {
        const options = res.data.data.map(this.normalizeParentOption).filter(item => item.code);
        this.parentOptions = this.ensureSelectedParent(options, selectedCode, selectedName);
      });
    },
    handleSubmit(form, done) {
      if (Number(form.regionLevel) === 0) {
        form.parentCode = this.topCode;
        form.ancestors = this.topCode;
        form.subCode = form.code;
      } else {
        const parentCode = Number(form.regionLevel) === 1 ? '' : form.parentCode;
        form.code = parentCode + form.subCode;
      }
      submit(form).then(
        () => {
          this.$message({
            type: 'success',
            message: '操作成功!',
          });
          this.initTree();
          this.regionForm.subCode = '';
          this.$refs.form.resetForm();
          done();
        },
        error => {
          done();
          window.console.log(error);
        }
      );
    },
    handleDelete() {
      if (validatenull(this.regionForm.code)) {
        this.$message.warning('请先选择一项区划');
        return;
      }
      this.$confirm(`确定将 [${this.regionForm.name}] 数据删除?`, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          return remove(this.treeCode);
        })
        .then(() => {
          this.$message({
            type: 'success',
            message: '操作成功!',
          });
          this.initTree();
          this.regionForm.subCode = '';
          this.$refs.form.resetForm();
        });
    },
    handleImport() {
      this.syncImportAction();
      openImportDialog(this, '行政区划', () => {
        this.initTree();
      });
    },
    syncImportAction() {
      const column = this.findColumn(this.excelOption.column, 'excelFile');
      if (!column) {
        return;
      }
      const covered = this.excelForm.isCovered;
      if (covered === '' || covered === undefined || covered === null) {
        column.action = '/blade-system/region/import-region';
      } else {
        column.action = `/blade-system/region/import-region?isCovered=${covered}`;
      }
    },
    handleDebug() {
      this.debugBox = true;
    },
    handleSync() {
      this.$confirm('确定同步最新行政区划数据？', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          this.syncLoading = true;
          return sync();
        })
        .then(() => {
          this.$message({
            type: 'success',
            message: '同步成功!',
          });
          this.initTree();
          this.regionForm = {};
        })
        .finally(() => {
          this.syncLoading = false;
        });
    },
    handleExport() {
      this.$confirm('是否导出行政区划数据?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        NProgress.start();
        exportBlob(`/blade-system/region/export-region?${this.website.tokenHeader}=${getToken()}`, {
          feedback: true,
        }).then(res => {
          downloadXls(res.data, `行政区划数据${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
          NProgress.done();
        });
      });
    },
    handleTemplate() {
      exportBlob(`/blade-system/region/export-template?${this.website.tokenHeader}=${getToken()}`, {
        feedback: true,
      }).then(res => {
        downloadXls(res.data, '行政区划模板.xlsx');
      });
    },
  },
};
</script>

<style>
.box {
  height: 800px;
}

.el-scrollbar {
  height: 100%;
}

.box .el-scrollbar__wrap {
  overflow: scroll;
}

.region-parent-select {
  width: 100%;
}

.region-page .region-page__tree-panel {
  flex: 0 0 17.5%;
  max-width: 17.5%;
}

.region-page .region-page__form-panel {
  flex: 0 0 82.5%;
  max-width: 82.5%;
}

.region-page__tree-panel .avue-tree__filter {
  padding: 0 8px 8px;
}

.region-page__tree-panel .avue-tree__filter .el-input,
.region-page__tree-panel .avue-tree__filter .el-input__wrapper {
  width: 100%;
  min-height: 32px;
}

.region-page__tree-panel .el-tree.el-tree--highlight-current {
  padding: 8px;
  box-sizing: border-box;
}

.region-page__form-panel .avue-form__group.avue-form__group--flex {
  padding: 12px;
  box-sizing: border-box;
}

@media (max-width: 768px) {
  .region-page .region-page__tree-panel,
  .region-page .region-page__form-panel {
    flex: 0 0 100%;
    max-width: 100%;
  }
}
</style>
