<template>
  <el-dialog
    title="区域选择"
    :visible="isShow"
    class="AreaSelect"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    width="50%"
    @close="cancel"
  >
    <div class="clearfix sel-area">
      <div class="float_left no-sel">
        <p class="sel-tit">地区选择</p>
        <div class="area-body">
          <el-tree
            :data="region_list"
            node-key="id"
            :expand-on-click-node="false"
          >
            <span slot-scope="{ node, data }" class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span>
                <el-button type="text" size="mini" @click="selArea(node, data)">
                  选择
                </el-button>
              </span>
            </span>
          </el-tree>
        </div>
      </div>
      <div class="float_left area-arrow">
        <i class="el-icon-arrow-right"></i>
      </div>
      <div class="float_left finish-sel">
        <p class="sel-tit">已选择</p>
        <div class="area-body">
          <el-tree
            :data="sel_region_list"
            node-key="id"
            :expand-on-click-node="false"
          >
            <span slot-scope="{ node, data }" class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span>
                <el-button
                  type="text"
                  size="mini"
                  @click="cancelSel(node, data)"
                >
                  取消
                </el-button>
              </span>
            </span>
          </el-tree>
        </div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button size="small" @click="cancel">取 消</el-button>
      <el-button size="small" type="primary" @click="confirm">确 定</el-button>
    </span>
  </el-dialog>
</template>

<script>
  import Region from "@/assets/area.json";
  export default {
    name: "AreaSelect",
    props: {
      isShow: {
        type: Boolean,
        default: false,
      },
      defaultRegion: {
        type: Array,
        default: () => {
          return [];
        },
      },
    },
    data() {
      return {
        sel_region_list: [],
        region_list: [],
        clone_area: [],
      };
    },
    created() {
      const OriRegion = this.$_common.deepClone(Region);
      this.region_list = OriRegion;
      // 复制区域数据为取消选择功能备用
      this.clone_area = this.$_common.deepClone(Region);
      // 重置选中数据
      this.sel_region_list = this.defaultRegion;

      // 根据选中数据，设置未选择区域列表
      if (this.defaultRegion.length) {
        const isP = this.defaultRegion.every((item) => item.isAll);
        // 省
        if (isP) {
          this.region_list = OriRegion.filter((item) => {
            return !this.defaultRegion.find(
              (itemF) => itemF.label === item.label
            );
          });
        } else {
          // 市
          this.defaultRegion.forEach((item) => {
            // 获取当前城市在原区域列表的index
            const indexP = this.region_list.findIndex(
              (itemO) => itemO.label === item.label
            );
            if (item.isAll) {
              this.region_list.splice(indexP, 1);
            } else {
              const isCP = item.children.every((itemC) => itemC.isAll);
              if (isCP) {
                this.region_list[indexP].children = this.region_list[
                  indexP
                ].children.filter((itemR) => {
                  return !item.children.find(
                    (itemF) => itemF.label === itemR.label
                  );
                });
              } else {
                //  县区
                item.children.forEach((itemDC) => {
                  const indexCC = this.region_list[indexP].children.findIndex(
                    (itemDO) => itemDO.label === itemDC.label
                  );
                  if (itemDC.isAll) {
                    this.region_list[indexP].children.splice(indexCC, 1);
                  } else {
                    this.region_list[indexP].children[
                      indexCC
                    ].children = this.region_list[indexP].children[
                      indexCC
                    ].children.filter((itemDR) => {
                      return !itemDC.children.find(
                        (itemDF) => itemDF.label === itemDR.label
                      );
                    });
                  }
                });
              }
            }
          });
        }
      }
    },
    methods: {
      // 选择区域
      selArea(node, area) {
        if (node.level === 1) {
          /* --------第一级------- */
          // 获取当前城市在未选择区域列表的下标
          const index = this.region_list.findIndex(
            (item) => area.label === item.label
          );
          // 获取当前城市在已选择城市的下标
          const fnIndex = this.sel_region_list.findIndex(
            (item) => area.label === item.label
          );
          if (fnIndex === -1) {
            this.sel_region_list.push(area);
          } else {
            this.sel_region_list[fnIndex].children = this.sel_region_list[
              fnIndex
            ].children.concat(this.region_list[index].children);
          }
          this.region_list.splice(index, 1);
        } else if (node.level === 2) {
          /* --------第二级------- */
          // 获取当前城市的父级在未选择区域列表的下标
          const pIndex = this.region_list.findIndex(
            (item) => item.label === node.parent.data.label
          );
          // 获取当前城市在未选择区域列表的下标
          const nIndex = this.region_list[pIndex].children.findIndex(
            (item) => item.label === area.label
          );
          // 获取当前城市的父级在已选择区域列表的下标
          const fiIndex = this.sel_region_list.findIndex(
            (item) => item.label === node.parent.data.label
          );
          // 当前城市的父级没有被选中过
          if (fiIndex === -1) {
            this.sel_region_list.push({
              ...node.parent.data,
              children: [{ ...area }],
            });
          } else {
            // 获取当前城市在已选择城市的下标
            const fnIndex = this.sel_region_list[fiIndex].children.findIndex(
              (item) => item.label === area.label
            );
            if (fnIndex === -1) {
              this.sel_region_list[fiIndex].children.push(area);
            } else {
              this.sel_region_list[fiIndex].children[
                fnIndex
              ].children = this.sel_region_list[fiIndex].children[
                fnIndex
              ].children.concat(
                this.region_list[pIndex].children[nIndex].children
              );
            }
          }
          // 把当前城市从未选择区域列表移除
          this.region_list[pIndex].children.splice(nIndex, 1);
          // 当市级城市被全部选中后，把当前省从未选择区域列表移除
          if (this.region_list[pIndex].children.length === 0) {
            this.region_list.splice(pIndex, 1);
          }
        } else if (node.level === 3) {
          /* --------第三级------- */
          // 获取祖父级数据
          const grandparent = node.parent.parent;
          // 获取父级数据
          const parent = node.parent;
          // 获取祖父级数据在已选择区域列表的下标
          const gFIndex = this.sel_region_list.findIndex(
            (item) => item.label === grandparent.data.label
          );
          // 判断祖父级是否被选中
          if (gFIndex === -1) {
            this.sel_region_list.push({
              ...grandparent.data,
              children: [
                {
                  ...parent.data,
                  children: [{ ...area }],
                },
              ],
            });
          } else {
            // 判断父级是否被选中过
            const fIndex = this.sel_region_list[gFIndex].children.findIndex(
              (item) => item.label === parent.data.label
            );
            if (fIndex === -1) {
              this.sel_region_list[gFIndex].children.push({
                ...parent.data,
                children: [{ ...area }],
              });
            } else {
              this.sel_region_list[gFIndex].children[fIndex].children.push(
                area
              );
            }
          }
          // 获取当前城市的祖父级在未选择区域列表的下标
          const gIndex = this.region_list.findIndex(
            (item) => item.label === grandparent.data.label
          );
          // 获取当前城市的父级在未选择区域列表的下标
          const prIndex = this.region_list[gIndex].children.findIndex(
            (item) => item.label === parent.data.label
          );
          // 获取当前城市在未选择区域列表的下标
          const noIndex = this.region_list[gIndex].children[
            prIndex
          ].children.findIndex((item) => item.label === area.label);
          // 把当前城市从未选择区域列表移除
          this.region_list[gIndex].children[prIndex].children.splice(
            noIndex,
            1
          );
          // 当县级城市被全部选中后，把当前县从未选择区域列表移除
          if (
            this.region_list[gIndex].children[prIndex].children.length === 0
          ) {
            this.region_list[gIndex].children.splice(prIndex, 1);
          }
          // 当市级城市被全部选中后，把当前市从未选择区域列表移除
          if (this.region_list[gIndex].children.length === 0) {
            this.region_list.splice(gIndex, 1);
          }
        }
      },
      // 取消选择
      cancelSel(node, area) {
        if (node.level === 1) {
          /* --------第一级------- */
          // 获取当前城市在已选择区域列表的下标
          const index = this.sel_region_list.findIndex(
            (item) => area.label === item.label
          );
          this.sel_region_list.splice(index, 1);
          // 获取当前城市在所有城市列表的下标
          const nIndex = this.clone_area.findIndex(
            (item) => item.label === area.label
          );
          // 获取当前城市在未选择列表的下标
          const noIndex = this.region_list.findIndex(
            (item) => item.label === area.label
          );
          // 重新设置未选择区域列表
          if (noIndex === -1) {
            this.region_list.splice(nIndex, 0, area);
          } else {
            this.region_list[noIndex].children = this.region_list[
              noIndex
            ].children.concat(area.children);
          }
        } else if (node.level === 2) {
          /* --------第二级------- */
          // 获取当前城市的父级在已选择区域列表的下标
          const pIndex = this.sel_region_list.findIndex(
            (item) => item.label === node.parent.data.label
          );
          // 获取当前城市在已选择区域列表的下标
          const nIndex = this.sel_region_list[pIndex].children.findIndex(
            (item) => item.label === area.label
          );
          // 把当前城市从 已选择区域列表 移除
          this.sel_region_list[pIndex].children.splice(nIndex, 1);
          // 获取当前城市的父级在所有区域的下标
          const cpIndex = this.clone_area.findIndex(
            (item) => item.label === this.sel_region_list[pIndex].label
          );
          // 获取当前城市的父级在未选择区域列表的下标
          const noPIndex = this.region_list.findIndex(
            (item) => item.label === this.sel_region_list[pIndex].label
          );
          if (noPIndex === -1) {
            // 当前城市的父级在未选择区域列表不存在
            this.region_list.splice(cpIndex, 0, {
              ...node.parent.data,
              children: [
                {
                  ...area,
                },
              ],
            });
          } else {
            // 当前城市的父级在未选择区域列表存在
            // 获取当前城市在未选择区域列表的下标
            const noIndex = this.region_list[noPIndex].children.findIndex(
              (item) => item.label === area.label
            );
            if (noIndex === -1) {
              // 获取当前城市在所有区域列表的下标
              const cnIndex = this.clone_area[cpIndex].children.findIndex(
                (item) => item.label === area.label
              );
              this.region_list[noPIndex].children.splice(cnIndex, 0, area);
            } else {
              this.region_list[noPIndex].children[
                noIndex
              ].children = this.region_list[noPIndex].children[
                noIndex
              ].children.concat(area.children);
            }
          }
          // 当市级城市全部被移除后，把当前省从已选择区域列表移除
          if (this.sel_region_list[pIndex].children.length === 0) {
            this.sel_region_list.splice(pIndex, 1);
          }
        } else if (node.level === 3) {
          /* --------第三级------- */
          // 获取祖父级数据
          const grandparent = node.parent.parent;
          // 获取父级数据
          const parent = node.parent;
          // 获取祖父级数据在已选择区域列表的下标
          const gFIndex = this.sel_region_list.findIndex(
            (item) => item.label === grandparent.data.label
          );
          // 获取当前城市的父级在已选择区域列表的下标
          const pIndex = this.sel_region_list[gFIndex].children.findIndex(
            (item) => item.label === parent.label
          );
          // 获取当前城市在已选择区域列表的下标
          const nIndex = this.sel_region_list[gFIndex].children[
            pIndex
          ].children.findIndex((item) => item.label === area.label);
          // 把当前城市从 已选择区域列表 移除
          this.sel_region_list[gFIndex].children[pIndex].children.splice(
            nIndex,
            1
          );
          // 获取祖父级数据在所有区域的下标
          const cgpIndex = this.clone_area.findIndex(
            (item) => item.label === grandparent.label
          );
          // 获取当前城市的父级在所有区域的下标
          const cpIndex = this.clone_area[cgpIndex].children.findIndex(
            (item) => item.label === parent.label
          );
          // 获取祖父级数据在未选择区域列表的下标
          const noGpIndex = this.region_list.findIndex(
            (item) => item.label === grandparent.label
          );
          if (noGpIndex === -1) {
            // 当前城市的祖父级在未选择区域列表不存在
            this.region_list.splice(cgpIndex, 0, {
              ...grandparent.data,
              children: [
                {
                  ...parent.data,
                  children: [
                    {
                      ...area,
                    },
                  ],
                },
              ],
            });
          } else {
            // 当前城市的祖父级在未选择区域列表存在
            // 获取当前城市父级未选择区域列表的下标
            const noPIndex = this.region_list[noGpIndex].children.findIndex(
              (item) => item.label === parent.label
            );
            if (noPIndex === -1) {
              // 当前城市的父级在未选择区域列表不存在
              this.region_list[noGpIndex].children.splice(cpIndex, 0, {
                ...parent.data,
                children: [
                  {
                    ...area,
                  },
                ],
              });
            } else {
              // 当前城市的父级在未选择区域列表存在
              // 获取当前城市在所有区域列表的下标
              const cnIndex = this.clone_area[cgpIndex].children[
                cpIndex
              ].children.findIndex((item) => item.label === area.label);
              this.region_list[noGpIndex].children[noPIndex].children.splice(
                cnIndex,
                0,
                area
              );
            }
          }
          // 当县级城市全部被移除后，把当前市从已选择区域列表移除
          if (
            this.sel_region_list[gFIndex].children[pIndex].children.length === 0
          ) {
            this.sel_region_list[gFIndex].children.splice(pIndex, 1);
          }
          // 当市级城市全部被移除后，把当前省从已选择区域列表移除
          if (this.sel_region_list[gFIndex].children.length === 0) {
            this.sel_region_list.splice(gFIndex, 1);
          }
        }
      },
      // 关闭弹窗
      cancel() {
        this.$emit("cancel");
      },
      // 确 定
      confirm() {
        /* ----------------省---------------- */
        this.sel_region_list.forEach((item) => {
          const originProvince = this.clone_area.find(
            (itemR) => itemR.label === item.label
          );
          /* ---------------市----------------- */
          if (item.children && item.children.length) {
            item.children.forEach((itemC) => {
              const originCity = originProvince.children.find(
                (itemR) => itemR.label === itemC.label
              );
              /* --------------县区------------------ */
              if (itemC.children && itemC.children.length) {
                // 判断当前城市的下级是否全部选中
                itemC.isAll =
                  originCity.children.length === itemC.children.length;
                // 判断当前省的下级是否全部选中
                item.isAll =
                  originProvince.children.length === item.children.length &&
                  itemC.isAll;
              }
            });
          }
        });
        this.$emit("confirm", this.sel_region_list);
      },
    },
  };
</script>

<style scoped>
  .sel-area > div {
    width: 46%;
  }

  .sel-tit {
    padding-bottom: 10px;
    color: #222222;
  }

  .sel-area > .area-arrow {
    height: 467px;
    width: 7%;
    text-align: center;
    line-height: 467px;
    font-size: 30px;
    color: #999999;
  }

  .area-body {
    border: 1px solid #ededed;
    border-radius: 4px;
    height: 467px;
    width: 100%;
    overflow-y: auto;
    padding: 16px;
    padding-bottom: 0;
  }
  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
</style>
