<script setup lang="ts">
import { reactive, ref, onMounted, computed, nextTick, watch } from "vue";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { useNav } from "/@/layout/hooks/nav";
import { responseHandle } from "/@/utils/responseHandle";
import { useUserStoreHook } from "/@/store/modules/user";
import { useCompany } from "/@/hooks/core/useCompany";
import { ElMessage } from "element-plus";

import {
  httpRoleAll,
  httpMenuAll,
  httpUpdate,
  httpDetail
} from "/@/api/interest/action";

defineOptions({
  name: "action"
});

const { logout } = useNav();
const { currentCompany } = useCompany();

const roleList = ref([]);
const loading = ref(true);
const powers = ref([]);
const backupMenuactionList = ref([]);
const menuactionList = ref([]);
const editType = ref("add");
const action_list = ref([]);
const action_data_list = ref([]);
const private_data_list = ref([]);
const ruleForm = reactive({
  roleid: "",
  role_name: "",
  level: "1",
  action: [],
  private_data: []
});
// 全选/全不选
const handleCheckAllChange = (checkAll, index, item, subIndex) => {
  menuactionList.value[index].child[subIndex].checkAll = checkAll;
  // this.$set(menuactionList.value, index, item);
  menuactionList.value[index].child[subIndex].action.forEach(element => {
    const findindex = menuactionList.value[index].child[
      subIndex
    ].checkList.findIndex(findItem => String(findItem) === String(element.id));
    if (checkAll && findindex == -1) {
      menuactionList.value[index].child[subIndex].checkList.push(
        String(element.id)
      );
    } else if (!checkAll && findindex > -1) {
      menuactionList.value[index].child[subIndex].checkList.splice(
        findindex,
        1
      );
    }
  });
};
// 全选/全不选
const handleFieldAllChange = (fieldAll, index, item, subIndex) => {
  menuactionList.value[index].child[subIndex].fieldAll = fieldAll;
  // this.$set(menuactionList.value, index, item);
  menuactionList.value[index].child[subIndex].action_data.forEach(element => {
    const findindex = menuactionList.value[index].child[
      subIndex
    ].fieldList.findIndex(findItem => String(findItem) === String(element.id));
    if (fieldAll && findindex == -1) {
      menuactionList.value[index].child[subIndex].fieldList.push(
        String(element.id)
      );
    } else if (!fieldAll && findindex > -1) {
      menuactionList.value[index].child[subIndex].fieldList.splice(
        findindex,
        1
      );
    }
  });
};
// 复选框组内的选中/不选中
const handleCheckedGroupChange = (event, index, item, subIndex) => {
  menuactionList.value[index].child[subIndex].checkAll = menuactionList.value[
    index
  ].child[subIndex].action.every(
    evitem =>
      menuactionList.value[index].child[subIndex].checkList.findIndex(
        finditem => String(finditem) === String(evitem.id)
      ) > -1
  );
  // this.$set(menuactionList.value, index, item);
};
// 复选框组内的选中/不选中
const handleFieldGroupChange = (event, index, item, subIndex) => {
  menuactionList.value[index].child[subIndex].fieldAll = menuactionList.value[
    index
  ].child[subIndex].action_data.every(
    evitem =>
      menuactionList.value[index].child[subIndex].fieldList.findIndex(
        finditem => String(finditem) === String(evitem.id)
      ) > -1
  );
  // this.$set(menuactionList.value, index, item);
};

// 单项复选框选中/不选中
const handleCheckedChange = (checked, id, index, subIndex, item) => {
  // console.log(checked, id, index, subIndex);
  if (checked) {
    // 选中时检查pid的选中状态
    menuactionList.value[index].child[subIndex].checkList.indexOf(id) == -1 &&
      menuactionList.value[index].child[subIndex].checkList.push(String(id));
  } else {
    const find = menuactionList.value[index].child[
      subIndex
    ].checkList.findIndex(e => e == id);
    if (find > -1) {
      menuactionList.value[index].child[subIndex].checkList.splice(find, 1);
    }
    menuactionList.value[index].child[subIndex].checkAll = false;
  }
  // this.$set(menuactionList.value, index, item);
};
// 单项复选框选中/不选中
const handleFieldChange = (checked, id, index, subIndex, item) => {
  // console.log(checked, id, index, subIndex);
  if (checked) {
    // 选中时检查pid的选中状态
    menuactionList.value[index].child[subIndex].fieldList.indexOf(id) == -1 &&
      menuactionList.value[index].child[subIndex].fieldList.push(String(id));
  } else {
    const find = menuactionList.value[index].child[
      subIndex
    ].fieldList.findIndex(e => e == id);
    if (find > -1) {
      menuactionList.value[index].child[subIndex].fieldList.splice(find, 1);
    }
    menuactionList.value[index].child[subIndex].fieldAll = false;
  }
  // this.$set(menuactionList.value, index, item);
  // console.log(menuactionList.value[index].child[subIndex]);
};
//选择角色
const switchRoleHandle = async item => {
  const { id } = item;
  ruleForm.roleid = id;
  await nextTick(async () => {
    await refreshRoleDetail(id);
  });
};
// 保存
const submitForm = async () => {
  if (loading.value) return;
  action_list.value = [];
  action_data_list.value = [];
  private_data_list.value = [];
  menuactionList.value.forEach(x => {
    x.child.forEach(y => {
      action_data_list.value.push(...y.fieldList);
      action_list.value.push(...y.checkList);
      if (String(y.is_private_change) === "1") {
        private_data_list.value.push(y.id);
      }
    });
  });

  if (action_list.value.length === 0) {
    ElMessage.error("请选择功能!");
    return;
  }
  const model = {
    roleid: ruleForm.roleid,
    role_name: ruleForm.role_name,
    level: ruleForm.level,
    action: action_list.value,
    // action_data: this.action_data,
    private_data: private_data_list.value
  };
  loading.value = true;
  const { code, message } = await httpUpdate(model);
  responseHandle({
    code,
    message,
    logout,
    handler: () => {
      ElMessage.success(message);
    }
  });
  loading.value = false;
};
const getMenuAll = async () => {
  const { code, data, message } = await httpMenuAll({ level: "0,2" });

  console.log(data);

  responseHandle({
    code,
    message,
    logout,
    handler: () => {
      let arr = JSON.parse(JSON.stringify(data ?? []));
      arr = arr.filter(item => item.child && item.child.length > 0);

      arr = arr.map(x => {
        x.child.map(y => {
          y.checkAll = false;
          y.checkList = [];
          y.fieldAll = false;
          y.fieldList = [];
          y.is_private_change = "0";
          if (String(y.is_private) === "0") {
            y.private = [];
          } else {
            y.private = [
              {
                id: "0",
                label: "公有数据"
              },
              {
                id: "1",
                label: "私有数据"
              }
            ];
          }
          return y;
        });
        return x;
      });
      backupMenuactionList.value = arr;
    }
  });
};

const getRoleAll = async () => {
  const { code, data, message } = await httpRoleAll({
    companyNo: currentCompany.value.companyNo
  });

  responseHandle({
    code,
    message,
    logout,
    handler: () => {
      roleList.value = data ?? [];
    }
  });
};

// 刷新角色详情
const refreshRoleDetail = async roleid => {
  loading.value = true;
  const { code, data, message } = await httpDetail({ roleid });
  responseHandle({
    code,
    message,
    logout,
    handler: async () => {
      const { action, action_data, private_data, id, role_name, level } =
        data ?? {};
      ruleForm.roleid = id;
      ruleForm.role_name = role_name ?? "";
      ruleForm.level = level ?? "1";
      action_list.value = action ?? [];
      action_data_list.value = action_data ?? [];
      private_data_list.value = private_data ?? [];
      await refreshRoleCheckAllStatus();
    }
  });
  loading.value = false;
};
// 刷新选择状态
const refreshRoleCheckAllStatus = async () => {
  menuactionList.value = JSON.parse(JSON.stringify(backupMenuactionList.value));
  console.log(private_data_list.value);
  menuactionList.value.forEach((x, xi) => {
    if (x?.child?.length > 0) {
      x.child.forEach((y, yi) => {
        // let id = y.id;
        if (y?.action?.length > 0) {
          y.action.forEach(z => {
            const Aindex = action_list.value.findIndex(
              a => String(a) === String(z.id)
            );
            if (Aindex !== -1) {
              y.checkList.push(action_list.value[Aindex]);
            }
            if (y.action.length === y.checkList.length) {
              y.checkAll = true;
            }
          });
        }
        if (y?.action_data?.length > 0) {
          y.action_data.map(z => {
            const Bindex = action_data_list.value.findIndex(
              a => String(a) === String(z.id)
            );
            if (Bindex !== -1) {
              y.fieldList.push(action_data_list.value[Bindex]);
            }
          });
          if (y.action_data.length === y.fieldList.length) {
            y.fieldAll = true;
          }
        }
        if (y.private && y.private.length === 2) {
          let Cindex =
            private_data_list.value.length > 0
              ? private_data_list.value.findIndex(
                  a => String(a) === String(y.id)
                )
              : -1;
          if (Cindex !== -1) {
            y.is_private_change = "1";
          } else {
            y.is_private_change = "0";
          }
        } else {
          y.is_private_change = "0";
        }
      });
    }
  });
};
async function onSearch() {
  if (!currentCompany.value.companyNo) {
    ElMessage.warning("请选择一个公司");
    return;
  }

  loading.value = true;
  await getRoleAll();
  await getMenuAll();
  if (roleList?.value.length > 0) {
    await refreshRoleDetail(roleList.value[0].id);
  }
  loading.value = false;
}

let indeterminateCheck = computed(() => {
  return item => {
    // 选中子节点的数量
    const selectItemLength = item.action.filter(
      filitem =>
        item.checkList.findIndex(
          finditem => String(finditem) === String(filitem.id)
        ) > -1
    ).length;
    // 未选中子节点的数量
    const noSlectItemLength = item.action.filter(
      filitem =>
        item.checkList.findIndex(
          finditem => String(finditem) === String(filitem.id)
        ) == -1
    ).length;
    // // 当前节点的index
    // 存在选中子节点且存在未选中子节点为中间态
    return selectItemLength > 0 && noSlectItemLength > 0;
  };
});

let indeterminateField = computed(() => {
  return item => {
    // console.log(item);
    // 选中子节点的数量
    const selectItemLength = item.action_data.filter(
      filitem => item.fieldList.findIndex(finditem => String(finditem) === String(filitem.id)) > -1
    ).length;

    // 未选中子节点的数量
    const noSlectItemLength = item.action_data.filter(
      filitem =>item.fieldList.findIndex(finditem => String(finditem) === String(filitem.id)) == -1
    ).length;
    // // 当前节点的index
    // 存在选中子节点且存在未选中子节点为中间态
    return selectItemLength > 0 && noSlectItemLength > 0;
  };
});

onMounted(() => {
  powers.value = useUserStoreHook().getMenuActions("action");
  if (powers.value.some(i => i == "001")) {
    onSearch();
  }
});

watch(
  () => currentCompany.value,
  () => onSearch()
);
</script>

<template>
  <div class="action" v-loading="loading && currentCompany.companyNo">
    <div v-show="powers.some(i => i == '001') && currentCompany.companyNo">
      <div class="action_show">
        <div class="action_show_box">
          <ul class="role-list">
            <p class="role-list__title">角色列表</p>
            <!--  -->
            <!--  -->
            <!-- v-if="isBtnDisabled && item.id == roleActive.id" -->
            <p
              v-if="roleList.length == 0"
              style="line-height: 60px; text-align: center; color: #858599"
            >
              暂无数据
            </p>
            <li
              v-for="(item, index) in roleList"
              :key="'role' + index"
              class="role-list__item"
              :class="{ active: item.id == ruleForm.roleid }"
              @click="!loading && switchRoleHandle(item)"
            >
              {{ item.role_name }}
              <el-button
                v-if="loading && item.id == ruleForm.roleid"
                class="fr"
                link
                :size="'mini'"
                :icon="useRenderIcon('Loading')"
              />
            </li>
          </ul>
          <div class="rule-view">
            <div class="rule-list" style="padding: 0 0 100px 0">
              <el-row
                v-for="(item, index) in menuactionList"
                :key="'menu' + item.id + index"
              >
                <el-col
                  v-if="item.child && item.child.length > 0"
                  class="ffff"
                  :span="24"
                >
                  <div class="ftitle">
                    <div
                      v-for="(si, sii) in item.menu_name"
                      :key="'title' + sii + si"
                    >
                      {{ si }}
                    </div>
                  </div>
                  <div class="fbody">
                    <div
                      class="fbody-item"
                      v-for="(subItem, subIndex) in item.child"
                      :key="'yemian' + subItem.id + subIndex"
                    >
                      <template
                        v-if="
                          !(
                            subItem.action &&
                            subItem.action.length === 0 &&
                            subItem.action_data &&
                            subItem.action_data.length === 0
                          )
                        "
                      >
                        <div class="stitle clear">
                          <span class="_h2 fl">{{ subItem.menu_name }}</span>
                          <el-radio-group
                            style="margin: 0 0 0 20px"
                            class="fl"
                            size="small"
                            v-if="
                              subItem &&
                              subItem.private &&
                              subItem.private.length === 2
                            "
                            v-model="subItem.is_private_change"
                          >
                            <el-radio-button
                              size="small"
                              v-for="(radioN, ri) in subItem.private"
                              :key="radioN.label + ri"
                              :label="radioN.id"
                              >{{ radioN.label }}</el-radio-button
                            >
                          </el-radio-group>
                        </div>
                        <div
                          class="scheck"
                          v-if="subItem.action && subItem.action.length > 0"
                        >
                          <div class="checkAll">
                            <el-checkbox
                              v-model="subItem.checkAll"
                              size="small"
                              :disabled="editType === 'view'"
                              :indeterminate="indeterminateCheck(subItem)"
                              @change="
                                handleCheckAllChange(
                                  $event,
                                  index,
                                  item,
                                  subIndex
                                )
                              "
                              >功能全选</el-checkbox
                            >
                          </div>
                          <div class="checkItem">
                            <el-checkbox-group
                              size="small"
                              v-model="subItem.checkList"
                              :disabled="editType === 'view'"
                              @change="
                                handleCheckedGroupChange(
                                  $event,
                                  index,
                                  item,
                                  subIndex
                                )
                              "
                            >
                              <el-checkbox
                                size="small"
                                :disabled="editType === 'view'"
                                v-for="children in subItem.action"
                                :key="'checkItem' + children.id"
                                :label="String(children.id)"
                                @change="
                                  handleCheckedChange(
                                    $event,
                                    String(children.id),
                                    index,
                                    subIndex,
                                    item
                                  )
                                "
                                >{{ children.action_name }}</el-checkbox
                              >
                            </el-checkbox-group>
                          </div>
                        </div>
                        <div
                          class="sfield"
                          v-if="
                            subItem.action_data &&
                            subItem.action_data.length > 0
                          "
                        >
                          <div class="checkAll">
                            <el-checkbox
                              size="small"
                              v-model="subItem.fieldAll"
                              :disabled="editType === 'view'"
                              :indeterminate="indeterminateField(subItem)"
                              @change="
                                handleFieldAllChange(
                                  $event,
                                  index,
                                  item,
                                  subIndex
                                )
                              "
                              >字段全选</el-checkbox
                            >
                          </div>
                          <div class="checkItem">
                            <el-checkbox-group
                              v-model="subItem.fieldList"
                              size="small"
                              :disabled="editType === 'view'"
                              @change="
                                handleFieldGroupChange(
                                  $event,
                                  index,
                                  item,
                                  subIndex
                                )
                              "
                            >
                              <el-checkbox
                                v-for="children in subItem.action_data"
                                :key="'FieldItem' + children.id"
                                :label="children.id"
                                size="small"
                                :disabled="editType === 'view'"
                                @change="
                                  handleFieldChange(
                                    $event,
                                    children.id,
                                    index,
                                    subIndex,
                                    item
                                  )
                                "
                                >{{ children.field_name }}</el-checkbox
                              >
                            </el-checkbox-group>
                          </div>
                        </div>
                      </template>
                    </div>
                  </div>
                </el-col>
              </el-row>
            </div>
          </div>
        </div>

        <div class="rule-bottom" v-if="powers.some(i => i == '008')">
          <el-button size="small" type="primary" @click="submitForm"
            >提 交</el-button
          >
        </div>
      </div>
    </div>
    <NoAuth v-show="!powers.some(i => i == '001')" />

    <h1 class="warning-message" v-show="!currentCompany.companyNo">
      <el-button
        text
        size="large"
        :icon="useRenderIcon('warning-filled')"
        disabled
      />
      请在右上角选择一家业务公司
    </h1>
  </div>
</template>

<style scoped lang="scss">
.action {
  height: calc(100vh - 85px);
  position: relative;
  background: #fff;
  width: 100%;
  text-align: center;
  overflow: hidden;

  .action_show {
    position: relative;
    width: 100%;
    height: calc(100vh - 85px);

    .rule-bottom {
      padding: 20px 30px 8px 0;
      // background: #fff;
      // width: 100px;
      text-align: right;
      position: fixed;
      right: 0px;
      bottom: 0px;

      &::before {
        content: "";

        top: 0;
        right: 0;
        height: 2px;
        width: 100%;
        background-color: #e4e7ed;
        z-index: 1;
      }
    }

    .action_show_box {
      position: relative;
      height: 100%;
      // calc(100% - 50px);
      min-height: 100%;
      //calc(100% - 50px);

      display: flex;
      text-align: left;

      .role-list {
        position: relative;
        height: 100%;
        overflow-y: auto;
        width: 250px;
        padding: 8px 16px;
        min-height: 100%;
        flex-shrink: 0;

        &::after {
          content: "";
          position: absolute;
          top: 0;
          right: 0;
          height: 100%;
          width: 2px;
          background-color: #e4e7ed;
          z-index: 1;
        }

        .role-list__title {
          color: #b4b6c0;
          line-height: 32px;
        }

        .role-list__item {
          position: relative;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          height: 32px;
          line-height: 32px;
          padding-left: 8px;
          color: rgb(48, 49, 51);
          cursor: pointer;

          i {
            position: absolute;
            right: 0;
            line-height: 32px;
          }
        }

        .role-list__item.active {
          color: #63cbe7;
          background: #f7f7f7;
        }
      }

      .rule-view {
        position: relative;
        height: 100%;
        width: calc(100% - 250px);
        overflow-y: scroll;

        // padding: 0 0 0 16px;
        .ffff {
          width: 100%;
          display: flex;
          align-items: stretch;

          .ftitle {
            width: 50px;
            text-align: center;
            border-right: 1px solid #dfe6ec;
            border-bottom: 1px solid #dfe6ec;
            padding: 12px 14px;
            display: flex;
            align-items: center;
            flex-direction: column;
            justify-content: center;

            div {
              font-size: 17px;
              height: 22px;
              line-height: 22px;
              text-align: center;
              color: #97a8be;
            }
          }

          .fbody {
            width: calc(100% - 50px);

            .fbody-item {
              border-right: 1px solid #dfe6ec;
              border-bottom: 1px solid #dfe6ec;

              .stitle {
                padding: 15px 18px 10px 18px;
                border-bottom: 1px dashed #dfe6ec;
                font-size: 14px;
                color: #97a8be;

                ._h2 {
                  display: inline-block;
                  height: 24px;
                  line-height: 24px;

                  // width: 100px;
                }
              }

              .scheck {
                padding: 15px 0 10px 0;
                display: flex;
                width: 100%;

                .checkAll {
                  width: 110px;
                  text-align: right;
                  padding: 0 25px 0 0;
                }

                .checkItem {
                  width: calc(100% - 120px);
                }
              }

              .sfield {
                padding: 0 0 10px 0;
                display: flex;
                width: 100%;

                .checkAll {
                  width: 140px;
                  text-align: right;
                  padding: 0 35px 0 0;
                }

                .checkItem {
                  width: calc(100% - 140px);
                }
              }
            }
          }
        }
      }
    }
  }

  .warning-message {
    position: absolute;
    top: 50%;
    left: 50%;
    font-weight: 700;
    transform: translate(-50%, -50%);
    font-size: 16px;

    :deep(.el-button) {
      padding: 0px;
    }
  }
}
</style>
