<script setup lang="ts">
import useStore from '@/stores';
import { deepClone, showElMessage } from '@/utils/utils';
import { traduction } from '@/utils/language';
import { onMounted, ref, reactive, computed } from 'vue';
import LocaluserService from '../../../services/localuser.service';

import { useTable } from '@/hooks/web/useTable';
import { UserPrivil } from '@/model/base-enum';
import { getStoreData } from '@/utils/composition';
import { IconSearch } from '@computing/opendesign-icons';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { localuserTableColumns } from '../models/localuser.config';

import Dialog from '@/components/Dialog/Dialog.vue';
import UploadSshDialog from './components/UploadSshDialog.vue';
import UserInfoTemplate from './components/UserInfoTemplate.vue';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import SearchInput from '@/components/SearchInput/SearchInput.vue';
import SecondPassword from '@/components/SecondPassword/SecondPassword.vue';
import GlobalStoreService from '@/services/gloabal-store-service';
const globalStoreService = new GlobalStoreService();
const store = useStore();
const MAX_SUPPORT_COUNT: number = 16;
const INDEFINITE_NUMBER = 4294967295;

const {
  id,
  columns,
  tableData,
  total,
  showPagination,
  displayedTableData,
  currentPage,
  pageSize,
  pageSizes,
  layout,
  handleSizeChange,
  handleCurrentChange,
  getCurrentPage,
  getPageSize,
  setTableData,
  filterData,
} = useTable('lodaluser', localuserTableColumns, true, queryAccounts);

// 用户配置权限
const hasConfigUsers = checkPrivil(UserPrivil.userConfig);
// 配置自身权限
const hasConfigSelf = checkPrivil(UserPrivil.configSelf);
// 锁定状态
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
// 免密登录
const nopwd = getStoreData('loct', 'nopwd') || false;

// 原始数据 只请求一次，后面的分页和过滤都需要根据原始数据进行查询
let oldData: any = [];
const userCountState = ref(false);
const searchContent = ref('');
const drawerRefObj = ref();
let checkItem: any = reactive({});

// 操作类型
let operationType = '';
const dialog = ref();
let dialogConfig = reactive({
  title: traduction('COMMON_CONFIRM'),
  content: traduction('COMMON_ASK_OK'),
});
const passwordDialog = ref();
const uploadSshDialog = ref();

// 抽屉发生表单校验
function validate(key: string, value: boolean) {}

// 点击添加用户
function addUser() {
  drawerRefObj.value.changeVisible(true);
}

// 获取调用方法
function getAskFn() {
  let method = '';
  switch (operationType) {
    case 'delete':
      method = 'deleteUser';
      break;
    case 'disable':
    case 'enable':
      method = 'modifyUserState';
      break;
    case 'deleteSSHKey':
      method = 'deleteSSHKey';
      break;
    default:
      method = '';
  }
  return method;
}

// dialog弹窗 或者输入当前登录密码的弹窗 中的确认按钮点击 或者 取消按钮点击
function sureOperation(flag: boolean, password?: string) {
  if (flag) {
    let method: string = getAskFn();
    if (method === '') {
      return;
    }
    globalStoreService.setValue('isLoading', true);
    // 有password的时候是没有开启免密登录
    LocaluserService[method](checkItem.id, password ? password : '', !checkItem.state)
      .then(() => {
        showElMessage('success', traduction('COMMON_SUCCESS'));
        reLoadUserList();
        if (password) {
          passwordDialog.value.hide();
        } else {
          dialog.value.hide();
        }
        globalStoreService.setValue('isLoading', false);
      })
      .catch((error: any) => {
        globalStoreService.setValue('isLoading', false);
        if (password) {
          // 反生错误时，清除二次认证密码
          passwordDialog.value.clearPassword();
          const errorId = error.errors[0].errorId;
          if (errorId === 'ReauthFailed' || errorId === 'AuthorizationFailed') {
            passwordDialog.value.setErrorId();
          } else {
            passwordDialog.value.hide();
          }
        } else {
          dialog.value.hide();
        }
      });
  } else {
    dialog.value.hide();
  }
}

// 点击编辑edit、禁用disable、启用enable、删除delete、删除SSH公钥deleteSSHKey
function operation(item: any, type: string, flag: boolean) {
  if (flag) {
    return;
  }
  operationType = type;
  Object.assign(checkItem, deepClone(item));
  // 不需要当前登录密码认证
  if (nopwd && type !== 'edit') {
    // 打开确认弹窗
    dialog.value.show();
  } else {
    // 禁用、启用、删除
    if (type === 'disable' || type === 'enable' || type === 'delete' || type === 'deleteSSHKey') {
      passwordDialog.value.show();
    } else {
      // 编辑
      drawerRefObj.value.changeVisible(true, item, true);
    }
  }
}

// 点击弹窗中的保存按钮 value:输入框中的密码值
function interPassworSave(res: { reason: boolean; password: string }) {
  if (res.reason) {
    sureOperation(true, res.password);
  } else {
    passwordDialog.value.hide();
  }
}

// 点击上传（SSH公钥）
function uploadSSH(item: any) {
  Object.assign(checkItem, deepClone(item));
  uploadSshDialog.value.show();
}

// 点击删除（SSH公钥）
function deleteSSH(item: any) {
  operation(item, 'deleteSSHKey', false);
}

// 重新查询用户列表
function reLoadUserList() {
  oldData.splice(0);
  queryAccounts();
}

// 搜索输入框发生修改
function searchInput(val: string) {
  searchContent.value = val;
  queryAccounts();
}

// 获取用户数据列表
function queryAccounts() {
  if (oldData.length) {
    filterData(searchContent.value, 'userName');
    return;
  }

  globalStoreService.setValue('isLoading', true);
  LocaluserService.getUserList()
    .then((res: any) => {
      setTableData(res.length, res);
      userCountState.value = displayedTableData.value.length < MAX_SUPPORT_COUNT;
      oldData = deepClone(displayedTableData.value);
      // 分页和过滤都是在前端做的
      filterData(searchContent.value, 'userName');
      globalStoreService.setValue('isLoading', false);
    })
    .catch(() => {
      globalStoreService.setValue('isLoading', false);
    });
}

onMounted(() => {
  queryAccounts();
});
</script>

<template>
  <div class="localuser-box">
    <div class="top-content">
      <!-- 添加用户按钮 和 搜索框 -->
      <div class="add-search">
        <el-button
          v-if="hasConfigUsers && userCountState"
          id="add"
          type="primary"
          :disabled="isSystemLock"
          @click="addUser"
        >
          {{ $t('USER_ADD_ACCOUNT') }}
        </el-button>
        <div class="el-input-search">
          <SearchInput
            :id-str="'userSearchInput'"
            :value="searchContent"
            :placeholder="$t('LOGIN_USER_TIP')"
            @clear="searchInput"
            @keyup-enter="searchInput"
            @input="searchInput"
          />
        </div>
      </div>

      <!-- 表格数据 -->
      <el-table v-addId.table="id" :data="displayedTableData" border resizable>
        <el-table-column class="expand" type="expand" width="35">
          <template #default="scope">
            <div class="box">
              <div id="userNameAndValidate" class="tr">
                <span class="td key">{{ $t('COMMON_USERNAME') }}</span>
                <span class="td value">{{ scope.row.userName }}</span>
                <span class="td key">{{ $t('USER_VALIDATE') }}</span>
                <span class="td value">
                  {{
                    scope.row.validate === INDEFINITE_NUMBER
                      ? $t('SERVICE_VNC_INDEFINITE')
                      : scope.row.validate === 0
                        ? $t('SERVICE_LONG_TIME')
                        : scope.row.validate
                  }}
                </span>
              </div>

              <div id="roleIdAndLoginRole" class="tr">
                <span class="td key">{{ $t('COMMON_ROLE') }}</span>
                <span class="td value">
                  {{ $t('COMMON_ROLE_' + scope.row.roleId.toUpperCase()) }}
                </span>
                <span class="td key">{{ $t('COMMON_LOGIN_RULE') }}</span>
                <span class="td value">
                  <el-tag
                    v-for="(item, i) in scope.row.loginRole"
                    :key="i"
                    size="small"
                    type="success"
                    class="tag-item"
                  >
                    {{ $t('SECURITY_SECUTITY_CFG_RULE' + item) }}
                  </el-tag>
                </span>
              </div>

              <div id="loginInterfaceAndSsh" class="tr">
                <span class="td key">{{ $t('COMMON_LOGIN_INTERFACE') }}</span>
                <span class="td value">
                  <el-tag
                    v-for="(item, i) in scope.row.loginInterface"
                    :id="item"
                    :key="i"
                    size="small"
                    type="success"
                    class="tag-item"
                  >
                    {{ item }}
                  </el-tag>
                </span>
                <span class="td key">{{ $t('USER_SSH_PUBLIC_KEY') }}</span>
                <span class="td value">
                  <span v-if="scope.row.sshPublicKeyHash !== ''" class="ssh-value">
                    {{ scope.row.sshPublicKeyHash }}
                  </span>
                  <a
                    v-if="hasConfigSelf && scope.row.sshPublicKeyHash === '' && !isSystemLock"
                    :id="'uploadBtn' + scope.row.id"
                    class="icon-upload"
                    href="javascript:;"
                    @click="uploadSSH(scope.row)"
                  >
                    {{ $t('COMMON_UPLOAD') }}
                  </a>
                  <a
                    v-if="hasConfigSelf && scope.row.sshPublicKeyHash !== '' && !isSystemLock"
                    :id="'deleteBtn' + scope.row.id"
                    class="icon-upload"
                    href="javascript:;"
                    @click="deleteSSH(scope.row)"
                  >
                    {{ $t('COMMON_DELETE') }}
                  </a>
                </span>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column
          v-for="col in columns"
          :key="col.content"
          :label="col.title"
          :min-width="col.width"
        >
          <template #default="scope">
            <template v-if="col.content === 'roleId'">
              <span :id="col?.content + scope.row.id">
                {{ $t(`COMMON_ROLE_${scope.row['roleId'].toUpperCase()}`) }}
              </span>
            </template>
            <template v-else-if="col.content === 'loginInterface'">
              <span :id="col?.content + scope.row.id">
                <el-tag
                  v-for="(item, i) in scope.row[col.content]"
                  :id="item"
                  :key="i"
                  size="small"
                  type="success"
                  class="tag-item"
                >
                  {{ item }}
                </el-tag>
              </span>
            </template>
            <template v-else>
              <span :id="col?.content + scope.row.id">{{ scope.row[col?.content || ''] }}</span>
            </template>
          </template>
        </el-table-column>

        <!-- 操作 -->
        <el-table-column :label="$t('COMMON_OPERATE')" min-width="20%">
          <template #default="scope">
            <!-- 编辑 -->
            <span
              v-if="hasConfigSelf"
              :id="'opEdit' + scope.row.id"
              :class="['btn', isSystemLock ? 'disabled-btn' : '']"
              @click="operation(scope.row, 'edit', isSystemLock)"
            >
              {{ $t('COMMON_EDIT') }}
            </span>

            <!-- 禁用 -->
            <span
              v-if="scope.row.state && hasConfigUsers"
              :id="'opDisable' + scope.row.id"
              :class="['btn', !scope.row.canDisabled || isSystemLock ? 'disabled-btn' : '']"
              :title="scope.row.canDisbledTipSHow ? scope.row.unDisabledReason : ''"
              @click="operation(scope.row, 'disable', !scope.row.canDisabled || isSystemLock)"
            >
              {{ $t('COMMON_DISABLE') }}
            </span>

            <!-- 启用 -->
            <span
              v-if="!scope.row.state && hasConfigUsers"
              :id="'opEnable' + scope.row.id"
              :class="['btn', isSystemLock ? 'disabled-btn' : '']"
              @click="operation(scope.row, 'enable', isSystemLock)"
            >
              {{ $t('COMMON_ENABLE') }}
            </span>

            <!-- 删除 -->
            <span
              v-if="hasConfigSelf"
              :id="'opDelete' + scope.row.id"
              :class="[
                'btn',
                !scope.row.canDeleted || isSystemLock || !hasConfigUsers ? 'disabled-btn' : ''
              ]"
              :title="scope.row.unDeletedReason"
              @click="
                operation(
                  scope.row,
                  'delete',
                  !scope.row.canDeleted || isSystemLock || !hasConfigUsers
                )
              "
            >
              {{ $t('COMMON_DELETE') }}
            </span>
          </template>
        </el-table-column>

        <template #empty>
          <TableNoData />
        </template>
      </el-table>
    </div>

    <el-pagination
      v-if="showPagination"
      v-model:currentPage="currentPage"
      v-addId.pagination="'localUserPagination'"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      :layout="layout"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>

    <!-- 输入当前登录密码校验弹窗 -->
    <SecondPassword ref="passwordDialog" @close="interPassworSave" />

    <!-- 点击编辑 或者 添加的抽屉 -->
    <UserInfoTemplate ref="drawerRefObj" @cancel="reLoadUserList" />

    <!-- 免密登录时 禁用、启用、删除 的确认弹窗 -->
    <Dialog ref="dialog" :config="dialogConfig" @close="sureOperation" />

    <!-- 上传SSH公钥的弹窗 -->
    <UploadSshDialog
      ref="uploadSshDialog"
      :login-without-password="nopwd"
      :item="checkItem"
      @close="sureOperation"
      @cancel="reLoadUserList"
    />
  </div>
</template>

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

  .top-content {
    flex: 1;
    display: flex;
    flex-direction: column;

    :deep(.add-search) {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 16px;

      .el-input {
        width: 296px;

        .el-input__prefix-inner {
          display: flex;
          flex-direction: column;
          justify-content: center;

          .el-icon {
            font-size: 16px;
            cursor: pointer;
          }
        }
      }

      .el-input-search .el-input__inner {
        padding-top: 8px;
        padding-bottom: 8px;
      }
    }

    :deep(.el-table) {
      margin-left: 0;
      flex: 1;
      .tag-item {
        margin-right: 4px;
      }

      .tag-item:nth-last-child(1) {
        margin-right: 0;
      }

      .btn {
        margin-right: 8px;
        cursor: pointer;
        font-size: 12px;
        color: var(--o-color-primary);

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

      .btn:nth-last-child(1) {
        margin-right: 0;
      }

      .box {
        display: table;
        width: 100%;
        padding-left: 24px;

        .tr {
          display: table-row;

          .td {
            display: table-cell;
            color: var(--o-text-color-secondary);
            padding-bottom: 8px;

            .ssh-value {
              margin-right: 4px;
            }
          }

          .key {
            padding-right: 24px;
            white-space: nowrap;
          }

          .value {
            color: var(--o-text-color-primary);
            width: 50%;

            .icon-upload {
              color: var(--o-color-primary);
              text-decoration: none;

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

        .tr:nth-last-child(1) {
          .td {
            padding-bottom: 0;
          }
        }
      }
    }
  }

  :deep(.el-pagination) {
    margin-top: 16px;
  }

  :deep(.el-drawer.rtl) {
    width: 552px !important;
    margin-top: 48px;
    height: calc(100% - 48px);
    border-radius: 4px 4px 0 0;

    .el-drawer__header {
      padding: 24px 24px 16px;
      font-weight: bold;
      color: var(--o-text-color-primary);
      font-size: 16px;
      line-height: 24px;
      margin-bottom: 0;
    }

    .el-drawer__body {
      padding: 0;

      .el-textarea.is-disabled {
        background-color: rgba(235, 237, 243, 1);
      }
    }
  }
}
</style>
