<script setup lang="ts">
import useStore from '@/stores';
import { traduction } from '@/utils/language';
import { onMounted, reactive, ref, computed } from 'vue';
import { IconCheckBold } from '@computing/opendesign-icons';
import GlobalStoreService from '@/services/gloabal-store-service';
import { showElMessage, compareObjectEqual } from '@/utils/utils';
import { ITableColumns, ISensorsTable, ITableRow, RoleName } from '@/model/base-interface';
import {
  addCustomRoleHandler,
  deleteCustomRoleHandler,
  getPermissionManagementData,
  editPermissionManagementData,
} from './permission-management.server';
import { UserPrivil } from '@/model/base-enum';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import SecondPassword from '@/components/SecondPassword/SecondPassword.vue';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import { getStoreData } from '@/utils/composition';
import { getSecurityInfo } from '@/services/security-enhance.service';
import Dialog from '@/components/Dialog/Dialog.vue';

const globalStoreService = new GlobalStoreService();
const successMsg = traduction('COMMON_SUCCESS');
const errorMsg = traduction('COMMON_FAILED');
const store = useStore();
const CUSTOM_IDS = [9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21] as const;

// 权限
const securityConfig = checkPrivil(UserPrivil.securityConfig);
const isAdmin = checkPrivil(UserPrivil.userConfig);
const addCustomEnabled = ref(false);
const minAvailableId = ref<typeof CUSTOM_IDS[number]>();
const canAddCustom = computed(
  () => minAvailableId.value && addCustomEnabled.value && !isSystemLock.value && securityConfig);

const delDialog = ref();
const delDialogConfig = reactive({
  title: traduction('ALARM_OK'),
  content: traduction('SECURITY_DELETE_ROLE_WARNING'),
});

// 锁定状态
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});

let passwordDialog = ref();

const columns: ITableColumns[] = reactive([
  {
    title: 'SECURITY_ROLE_NAME',
    width: '9%',
    content: 'roleName',
  },
  {
    title: 'SECURITY_USER_CONFIGURATION',
    width: '9%',
    content: 'userConfigEnabled',
    id: 'configureUserCheckbox',
    disabled: true,
  },
  {
    title: 'SECURITY_GENERAL_SETTINGS',
    width: '9%',
    content: 'basicConfigEnabled',
    id: 'configureComponents',
  },
  {
    title: 'SECURITY_REMOTE_CONTROL',
    width: '9%',
    content: 'remoteControlEnabled',
    id: 'oemKvm',
  },
  {
    title: 'SECURITY_REMOTE_MEDIA',
    width: '9%',
    content: 'VMMEnabled',
    id: 'oemVmm',
  },
  {
    title: 'SECURITY_SECURITY_CONFIG',
    width: '9%',
    content: 'securityConfigEnabled',
    id: 'oemSecurityMgmt',
  },
  {
    title: 'HOME_POWER_CONTROL',
    width: '9%',
    content: 'powerControlEnabled',
    id: 'oemPowerControl',
  },
  {
    title: 'SECURITY_COMMISSIONING_DIAGNOSIS',
    width: '9%',
    content: 'diagnosisEnabled',
    id: 'oemDiagnosis',
  },
  {
    title: 'SECURITY_QUERYFUNCTION',
    width: '9%',
    content: 'queryEnabled',
    id: 'login',
    disabled: true,
  },
  {
    title: 'SECURITY_CONFIGUREITSELF',
    width: '9%',
    content: 'configureSelfEnabled',
    id: 'configureSelf',
    disabled: true,
  },
  {
    title: 'COMMON_OPERATE',
    width: '200px',
    content: 'operation',
  },
]);

let dataList: ISensorsTable[] = [];
let tableData: ISensorsTable[] = reactive([]);

type ActionType = 'add' | 'modify' | 'delete';
const modalFrom = ref<ActionType>();
let currentPage = ref(1);
let total = ref(0);
let pageSize = ref(10);
let editItem: any[] = [];
// 记录点击保存的数据在数据中的序号
let saveIndex: number = -1;

// 是否免密登录
const nopwd = getStoreData('loct', 'nopwd');

const kvmspt = computed(() => getStoreData('loct', 'kvmspt'));
const vmmspt = computed(() => getStoreData('loct', 'vmmspt'));

interface RoleConfig {
  roleName: string;
  sequence?: number;
  isOperation?: boolean;
}

const roleMap: Record<string, RoleConfig> = {
  [RoleName.administrator]: { roleName: 'COMMON_ROLE_ADMINISTRATOR', sequence: 1 },
  [RoleName.operator]: { roleName: 'COMMON_ROLE_OPERATOR', sequence: 2 },
  [RoleName.commonuser]: { roleName: 'COMMON_ROLE_COMMONUSER', sequence: 3 },
  [RoleName.noAccess]: { roleName: 'COMMON_ROLE_NOACCESS' },
  [RoleName.customRole1]: { roleName: 'COMMON_ROLE_CUSTOMROLE1', isOperation: true, sequence: 4 },
  [RoleName.customRole2]: { roleName: 'COMMON_ROLE_CUSTOMROLE2', isOperation: true, sequence: 5 },
  [RoleName.customRole3]: { roleName: 'COMMON_ROLE_CUSTOMROLE3', isOperation: true, sequence: 6 },
  [RoleName.customRole4]: { roleName: 'COMMON_ROLE_CUSTOMROLE4', isOperation: true, sequence: 7 },
  [RoleName.customRole5]: { roleName: 'COMMON_ROLE_CUSTOMROLE5', isOperation: true, sequence: 8 },
  [RoleName.customRole6]: { roleName: 'COMMON_ROLE_CUSTOMROLE6', isOperation: true, sequence: 9 },
  [RoleName.customRole7]: { roleName: 'COMMON_ROLE_CUSTOMROLE7', isOperation: true, sequence: 10 },
  [RoleName.customRole8]: { roleName: 'COMMON_ROLE_CUSTOMROLE8', isOperation: true, sequence: 11 },
  [RoleName.customRole9]: { roleName: 'COMMON_ROLE_CUSTOMROLE9', isOperation: true, sequence: 12 },
  [RoleName.customRole10]: { roleName: 'COMMON_ROLE_CUSTOMROLE10', isOperation: true, sequence: 13 },
  [RoleName.customRole11]: { roleName: 'COMMON_ROLE_CUSTOMROLE11', isOperation: true, sequence: 14 },
  [RoleName.customRole12]: { roleName: 'COMMON_ROLE_CUSTOMROLE12', isOperation: true, sequence: 15 },
  [RoleName.customRole13]: { roleName: 'COMMON_ROLE_CUSTOMROLE13', isOperation: true, sequence: 16 },
  [RoleName.customRole14]: { roleName: 'COMMON_ROLE_CUSTOMROLE14', isOperation: true, sequence: 17 },
  [RoleName.customRole15]: { roleName: 'COMMON_ROLE_CUSTOMROLE15', isOperation: true, sequence: 18 },
  [RoleName.customRole16]: { roleName: 'COMMON_ROLE_CUSTOMROLE16', isOperation: true, sequence: 19 },
};
 
function getColumns() {
  const hiddenIds: string[] = [];
  if (!kvmspt.value) {
    hiddenIds.push('oemKvm');
  }
  if (!vmmspt.value) {
    hiddenIds.push('oemVmm');
  }
  if (hiddenIds.length > 0) {
    const filtered = columns.filter(col => !hiddenIds.includes(col.id as string));
    columns.splice(0, columns.length, ...filtered);
  }
}

function getAbility() {
  getSecurityInfo().then(res => {
    addCustomEnabled.value = res?.ExtendedCustomRoleEnabled;
  });
}

function getData(act: boolean = false) {
  tableData.splice(0);

  // 如果请求过最新数据（为什么是最新：因为这里有编辑操作），那么不再发送请求，直接对现有请求数据做重新组合
  if (dataList.length > 0) {
    initShowData(dataList);
    return;
  }

  globalStoreService.setValue('isLoading', true);
  getPermissionManagementData()
    .then((data: any) => {
      if (data && data.Members) {
        initShowData(data.Members);
        globalStoreService.setValue('isLoading', false);
        const occupiedIds = data.Members.map((item: any) => item.ID);
        minAvailableId.value = CUSTOM_IDS.filter(id => !occupiedIds.includes(id))[0];
        if (act) {
          showElMessage('success', successMsg);
        }
      } else {
        globalStoreService.setValue('isLoading', false);
      }
    })
    .catch(() => {
      globalStoreService.setValue('isLoading', false);
    });
}

// 加工展示数据
function initShowData(list: any[]) {
  if (dataList.length === 0) {
    dataList = JSON.parse(JSON.stringify(list));
  }
  const transformedData: ITableRow[] = [];
  if (list && typeof list === 'object' && list instanceof Array) {
    list.forEach(member => {
      const { roleName, isOperation, sequence } = getRoleName(member.Name);

      if (roleName === 'COMMON_ROLE_NOACCESS') {
        return;
      }
      transformedData.push({
        id: member.ID,
        isOperation,
        roleName,
        userConfigEnabled: member.UserConfigEnabled,
        basicConfigEnabled: member.BasicConfigEnabled,
        remoteControlEnabled: member.RemoteControlEnabled,
        VMMEnabled: member.VMMEnabled,
        securityConfigEnabled: member.SecurityConfigEnabled,
        powerControlEnabled: member.PowerControlEnabled,
        diagnosisEnabled: member.DiagnosisEnabled,
        queryEnabled: member.QueryEnabled,
        configureSelfEnabled: member.ConfigureSelfEnabled,
        isSave: false,
        isEdit: false,
        sequence,
      });
    });
  }

  total.value = transformedData.length;
  const showList = transformedData.slice(
    (currentPage.value - 1) * pageSize.value,
    currentPage.value * pageSize.value,
  );
  tableData.push(...showList);
}

// 国际化 角色名称，以及设置可编辑状态
function getRoleName(id: RoleName) {
  let { roleName, isOperation, sequence } = roleMap[id];
  isOperation = isOperation ?? false;
  sequence = sequence ?? 1;
  return { roleName, isOperation, sequence };
}

// 点击编辑、保存、取消
function action(item: any, state: boolean, index: number, type?: Exclude<ActionType, 'add'>) {
  if (isSystemLock.value) {
    return;
  }
  modalFrom.value = type;
  // 点击编辑、取消
  if (!type) {
    if (state) {
      editItem[index] = JSON.parse(JSON.stringify(item));
    } else {
      Object.assign(item, editItem[index]);
    }
    item.isEdit = state;
  } else if (!setBtnStyle(item, index) && type === 'modify') {
    saveIndex = index;
    submitForm();
  } else {
    saveIndex = index;
    if (type === 'delete') {
      delDialog.value.show();
    }
  }
}

function deleteConfirm(reason: boolean): void {
  if (reason) {
    if (!nopwd) {
    // 修改弹窗显示状态
      passwordDialog.value.show();
    } else {
      deleteAction();
    }
  }
  delDialog.value.hide();
}

// 点击保存
function submitForm() {
  if (!nopwd) {
    // 修改弹窗显示状态
    passwordDialog.value.show();
  } else {
    reqAction();
  }
}

function reqAction(res?: { reason: boolean; password: string }) {
  const row = tableData[saveIndex];
  const params: any = {
    ID: row.id,
    UserConfigEnabled: row.userConfigEnabled,
    BasicConfigEnabled: row.basicConfigEnabled,
    RemoteControlEnabled: row.remoteControlEnabled,
    VMMEnabled: row.VMMEnabled,
    SecurityConfigEnabled: row.securityConfigEnabled,
    PowerControlEnabled: row.powerControlEnabled,
    DiagnosisEnabled: row.diagnosisEnabled,
  };

  if (res?.password) {
    params.ReauthKey = window.btoa(res.password);
  }

  editPermissionManagementData(params)
    .then(() => {
      // 如果保存成功需要重新获取数据
      dataList = [];
      passwordDialog.value.hide();
      getData(true);
    })
    .catch(() => {
      passwordDialog.value.setErrorId();
      passwordDialog.value.clearPassword();
    });
}

function addAction(res?: { reason: boolean; password: string }) {
  const params: any = {
    ID: minAvailableId.value,
    BasicConfigEnabled: false,
    DiagnosisEnabled: false,
    PowerControlEnabled: false,
    RemoteControlEnabled: false,
    SecurityConfigEnabled: false,
    UserConfigEnabled: false,
    VMMEnabled: false,
  };

  if (res?.password) {
    params.ReauthKey = window.btoa(res.password);
  }

  addCustomRoleHandler(params)
    .then(() => {
      dataList = [];
      passwordDialog.value.hide();
      getData(true);
    })
    .catch(() => {
      passwordDialog.value.setErrorId();
      passwordDialog.value.clearPassword();
    });
}

function addCustomRole(): void {
  modalFrom.value = 'add';
  if (isSystemLock.value) {
    return;
  }
  if (!nopwd) {
    passwordDialog.value.show();
  } else {
    addAction();
  }
}

function deleteAction(res?: { reason: boolean; password: string }): void {
  const params: any = {};

  if (res?.password) {
    params.ReauthKey = window.btoa(res.password);
  }

  deleteCustomRoleHandler(tableData[saveIndex].id, params)
    .then(() => {
      dataList = [];
      passwordDialog.value.hide();
      getData(true);
    })
    .catch(() => {
      passwordDialog.value.setErrorId();
      passwordDialog.value.clearPassword();
    });
}

// 点击弹窗中的保存按钮 value:输入框中的密码值
function interPasswordSave(res: { reason: boolean; password: string }) {
  if (res.reason) {
    switch (modalFrom.value) {
      case 'add':
        addAction(res);
        break;
      case 'modify':
        reqAction(res);
        break;
      case 'delete':
        deleteAction(res);
        break;
      default:
        break;
    }
  } else {
    passwordDialog.value.hide();
  }
}

// 设置保存按钮的可选状态
function setBtnStyle(item: any, index: number) {
  return compareObjectEqual(item, editItem[index], 'isEdit');
}

function handleSizeChange(val: number) {
  pageSize.value = val;
  getData();
}

function handleCurrentChange(val: number) {
  getData();
}

onMounted(() => {
  getAbility();
  getColumns();
  getData();
});
</script>

<template>
  <div id="authorityManagement" class="permission-management-box" :class="{ addCustomBox: canAddCustom }">
    <el-button
      v-if="canAddCustom" class="addCustomBtn"
      type="primary" @click="addCustomRole"
    >{{ $t('COMMON_ADD_CUSTOMROLE') }}</el-button>
    <div class="content">
      <el-table v-addId.table="'authorityManagementTable'" :data="tableData" border resizable>
        <el-table-column
          v-for="(item, index) in columns"
          :key="index"
          :prop="item.content"
          :label="$t(item.title)"
        >
          <template #default="scope">
            <span v-if="item.content === 'roleName'" :id="'roleName' + scope.row.id">
              {{ $t(scope.row[item.content]) }}
            </span>
            <span
              v-else-if="item.content === 'operation' && scope.row.isOperation"
              class="operation"
            >
              <!-- 编辑 -->
              <span
                v-if="!scope.row.isEdit"
                :id="'authorityEdit' + scope.row.id"
                :class="['btn', !securityConfig || isSystemLock ? 'disabled-btn' : '']"
                @click="action(scope.row, true, scope.$index)"
              >
                {{ !scope.row.MySession ? $t('COMMON_EDIT') : '' }}
              </span>
              <!-- 保存 -->
              <span
                v-if="scope.row.isEdit"
                :id="'authoritySave' + scope.row.id"
                :class="['btn', setBtnStyle(scope.row, scope.$index) ? 'disabled-btn' : '']"
                @click="action(scope.row, false, scope.$index, 'modify')"
              >
                {{ !scope.row.MySession ? $t('COMMON_SAVE') : '' }}
              </span>
              <span
                v-if="scope.row.isEdit && CUSTOM_IDS.includes(scope.row.id)"
                :id="'authoritySave' + scope.row.id"
                class="btn cancel"
                @click="action(scope.row, false, scope.$index, 'delete')"
              >
                {{ !scope.row.MySession ? $t('COMMON_DELETE') : '' }}
              </span>
              <!-- 取消 -->
              <span
                v-if="scope.row.isEdit"
                :id="'authorityCancel' + scope.row.id"
                class="btn cancel"
                @click="action(scope.row, false, scope.$index)"
              >
                {{ !scope.row.MySession ? $t('COMMON_CANCEL') : '' }}
              </span>
            </span>
            <span
              v-else-if="item.content !== 'operation'"
              :id="item.id + scope.row.id"
              class="state-value"
            >
              <!-- 图标 -->
              <el-icon
                v-if="scope.row[item.content] && !scope.row.isEdit"
                :id="item.id + 'CheckRes' + scope.row.id"
              >
                <IconCheckBold />
              </el-icon>
              <!-- 选择框 -->
              <el-checkbox
                v-if="scope.row.isEdit"
                v-model="scope.row[item.content]"
                v-addId.checkbox="item.id + 'Checkbox' + scope.row.id"
                label=""
                :disabled="item.disabled"
                size="large"
              ></el-checkbox>
            </span>
          </template>
        </el-table-column>
        <template #empty>
          <TableNoData />
        </template>
      </el-table>

      <SecondPassword ref="passwordDialog" @close="interPasswordSave" />
      <Dialog ref="delDialog" :config="delDialogConfig" @close="deleteConfirm" />
    </div>

    <el-pagination
      v-model:currentPage="currentPage"
      v-addId.pagination="'permissionPagination'"
      :page-sizes="[10, 15, 30, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<style lang="scss" scoped>
.permission-management-box {
  flex: 1;
  padding: 16px;
  background-color: var(--o-bg-color-base);
  border-radius: 0 4px 4px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;

  .addCustomBtn {
    position: absolute;
    top: 16px;
    left: 16px;
  }

  .content {
    padding-bottom: 16px;
    flex: 1;
    position: relative;

    :deep(.cell) {
      max-height: 19px;
      min-height: 19px;
      .state-value {
        color: var(--o-color-primary);
        font-size: 16px;

        .el-checkbox {
          height: auto;

          .el-checkbox__input {
            width: 14px;

            .el-checkbox__inner::after {
              top: 2px;
              left: 4px;
            }
          }
        }
      }
    }

    .operation {
      .btn {
        cursor: pointer;
        color: var(--o-color-primary);

        &:hover {
          color: var(--o-color-primary-secondary);
        }
      }

      .disabled-btn {
        cursor: not-allowed;
        color: var(--o-text-color-tertiary);
      }

      .cancel {
        margin-left: 8px;
      }
    }

    .dialog-title {
      display: flex;
      align-items: center;
      .title-text {
        font-size: 16px;
        line-height: 24px;
        font-weight: 900;
      }
      :deep(.el-icon) {
        margin-right: 5px;
        font-size: 18px;
      }
    }

    :deep(.el-table--border) {
      padding-top: 0;
    }
  }
}
.addCustomBox {
  padding-top: 64px !important;
  position: relative;
}
</style>
