<script setup lang="tsx">
import { ref, withDirectives } from 'vue';
import {
  type DropdownOption,
  type FormItemRule,
  NButton,
  NDropdown,
  NFormItem,
  NInput,
  NPopconfirm,
  NSwitch
} from 'naive-ui';
import {
  changeUserStatus,
  fetchDeleteUser,
  fetchGetDeptTree,
  fetchGetUserList,
  reqSyncUser,
  resetUserPwd
} from '@/service/api/system/user';
import { $t } from '@/locales';
import { useAppStore } from '@/store/modules/app';
import { useTable, useTableOperate } from '@/hooks/common/table';
import hasPermission from '@/directive/permission/hasPermission';
import UserAuthRoleOperateModal from '@/views/system/user/modules/user-auth-role-operate-modal.vue';
import UserOperateModal from './modules/user-operate-modal.vue';
import UserSearch from './modules/user-search.vue';

const appStore = useAppStore();

/** 部门树列表 */
const deptOptions = ref<Api.SystemManage.Dept[]>([]);
// 获取部门树列表
async function getDeptTree() {
  const { data, error } = await fetchGetDeptTree();
  if (!error) {
    deptOptions.value = data;
  }
}

const optionsDropdown: DropdownOption[] = [
  { key: 'resetPwd', label: '重置密码' },
  { key: 'authRole', label: '分配角色' }
];
// 重置密码
const pwdValue = ref('');
const pwdRule: FormItemRule = {
  required: true,
  trigger: ['input', 'blur'],
  validator
};
function validator() {
  const pattern = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!_%*#?&])[A-Za-z\d@$!_%*#?&]{8,}$/;
  if (!pattern.test(pwdValue.value)) {
    console.log('密码格式错误');
    return new Error('密码包含字母大小写、数字、特殊字符并且长度超过8位');
  }
  return true;
}
// 分配角色
const drawerVisibleRole = ref(false);
let userId: Api.SystemManage.User['userId'] = '';

const {
  columns,
  columnChecks,
  data,
  getData,
  getDataByPage,
  loading,
  mobilePagination,
  searchParams,
  resetSearchParams
} = useTable({
  apiFn: fetchGetUserList,
  showTotal: true,
  apiParams: {
    pageNum: 1,
    pageSize: 10,
    deptId: null,
    nickName: null,
    phonenumber: null,
    status: null
  },
  columns: () => [
    {
      type: 'selection',
      align: 'center',
      width: 48
    },
    {
      key: 'userId',
      title: '用户编号',
      align: 'center',
      width: 100
    },
    {
      key: 'userName',
      title: $t('page.manage.user.userName'),
      align: 'center',
      minWidth: 100
    },
    {
      key: 'nickName',
      title: $t('page.manage.user.nickName'),
      align: 'center',
      minWidth: 100
    },
    {
      key: 'dept',
      title: '部门',
      align: 'center',
      minWidth: 100,
      render: row => row.dept?.deptName || '-'
    },
    {
      key: 'phonenumber',
      title: $t('page.manage.user.userPhone'),
      align: 'center',
      width: 120
    },
    {
      key: 'status',
      title: $t('page.manage.user.userStatus'),
      align: 'center',
      width: 100,
      render: row => {
        if (row.status === null || (row.userId as number) === 1) {
          return null;
        }
        return (
          <NSwitch
            v-model:value={row.status}
            checked-value="0"
            unchecked-value="1"
            onUpdate:value={() => handleStatusChange(row)}
          />
        );
      }
    },
    {
      key: 'createTime',
      title: '创建时间',
      align: 'center',
      minWidth: 120
    },
    {
      key: 'operate',
      title: $t('common.operate'),
      align: 'center',
      width: 200,
      render: row => {
        if (row.userId === 1) return null;
        return (
          <div class="flex-center gap-8px">
            {withDirectives(
              <NButton type="primary" ghost size="small" onClick={() => edit(row.userId)}>
                {$t('common.edit')}
              </NButton>,
              [[hasPermission, ['system:user:edit']]]
            )}
            {withDirectives(
              <div>
                <NPopconfirm onPositiveClick={() => handleDelete(row.userId)}>
                  {{
                    default: () => $t('common.confirmDelete'),
                    trigger: () => (
                      <NButton type="error" ghost size="small">
                        {$t('common.delete')}
                      </NButton>
                    )
                  }}
                </NPopconfirm>
              </div>,
              [[hasPermission, ['system:user:remove']]]
            )}
            {withDirectives(
              <div>
                <NDropdown trigger="hover" options={optionsDropdown} onSelect={key => handleDropdownSelect(key, row)}>
                  <NButton type="warning" ghost size="small">
                    更多
                  </NButton>
                </NDropdown>
              </div>,
              [[hasPermission, ['system:user:resetPwd', 'system:user:edit']]]
            )}
          </div>
        );
      }
    }
  ]
});

const {
  drawerVisible,
  operateType,
  editingData,
  handleAdd,
  handleSimpleEdit,
  // handleEdit,
  checkedRowKeys,
  onBatchDeleted,
  onDeleted
  // closeDrawer
} = useTableOperate(data, getData, 'userId');

/** 选择部门 */
function handleSelectKeys(keys: Array<string>) {
  searchParams.deptId = keys[0];
  getDataByPage();
}

async function handleBatchDelete() {
  const { error } = await fetchDeleteUser(checkedRowKeys.value as string[]);
  if (!error) {
    onBatchDeleted();
  }
}

async function handleDelete(id: Api.SystemManage.User['userId']) {
  const { error } = await fetchDeleteUser([id]);
  if (!error) {
    onDeleted();
  }
}

async function edit(id: Api.SystemManage.User['userId']) {
  handleSimpleEdit(id);
}

// 用户状态修改
function handleStatusChange(row: Api.SystemManage.User) {
  const text = row.status === '0' ? '启用' : '停用';
  window.$dialog?.warning({
    title: '提示',
    content: `确定要${text}用户"${row.nickName}"吗？`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      return changeUserStatus(row.userId, row.status).then(res => {
        if (!res.error) {
          window.$message?.success(`${text}成功`);
        } else {
          row.status = row.status === '0' ? '1' : '0';
        }
      });
    },
    onNegativeClick: () => {
      row.status = row.status === '0' ? '1' : '0';
    },
    onClose: () => {
      row.status = row.status === '0' ? '1' : '0';
    },
    onEsc: () => {
      row.status = row.status === '0' ? '1' : '0';
    }
  });
}

// 点击更多
function handleDropdownSelect(key: string, row: Api.SystemManage.User) {
  if (key === 'resetPwd') {
    pwdValue.value = '';
    window.$dialog?.info({
      title: '提示',
      showIcon: false,
      positiveText: '确定',
      negativeText: '取消',
      content: () => {
        return (
          <NFormItem label={`请输入"${row.nickName}"的新密码`} rule={pwdRule}>
            <NInput v-model:value={pwdValue.value} />
          </NFormItem>
        );
      },
      onPositiveClick: () => {
        if (validator() !== true) return false;
        return resetUserPwd(row.userId, pwdValue.value).then(() => {
          window.$message?.success('密码重置成功');
        });
      }
    });
  } else if (key === 'authRole') {
    drawerVisibleRole.value = true;
    userId = row.userId;
  }
}

function handleSyncUser() {
  reqSyncUser().then(res => {
    if (res.error) return;
    window.$message?.success('同步成功');
    getDataByPage();
  });
}

async function init() {
  await getDeptTree();
}

init();
</script>

<template>
  <NGrid :x-gap="8" :y-gap="8" item-responsive responsive="screen">
    <!--<NGridItem span="4" class="flex-col">-->
    <!--  <NCard title="部门列表" class="h-full">-->
    <!--    <NTree-->
    <!--      block-line-->
    <!--      key-field="id"-->
    <!--      :data="deptOptions"-->
    <!--      default-expand-all-->
    <!--      virtual-scroll-->
    <!--      @update-selected-keys="handleSelectKeys"-->
    <!--      class="h-[calc(100vh-200px)]"-->
    <!--    />-->
    <!--  </NCard>-->
    <!--</NGridItem>-->
    <NGridItem span="24">
      <div class="h-full flex-col-stretch gap-8px overflow-hidden lt-sm:overflow-auto">
        <UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
        <NCard
          :title="$t('page.manage.user.title')"
          :bordered="false"
          size="small"
          class="sm:flex-1-hidden card-wrapper"
        >
          <template #header-extra>
            <TableHeaderOperation
              v-model:columns="columnChecks"
              :disabled-delete="checkedRowKeys.length === 0"
              :loading="loading"
              :has-perm="['system:user:add', 'system:user:remove']"
              @add="handleAdd"
              @delete="handleBatchDelete"
              @refresh="getData"
            >
              <template #middle>
                <NButton type="primary" ghost size="small" @click="handleSyncUser">同步组织架构</NButton>
              </template>
            </TableHeaderOperation>
          </template>
          <NDataTable
            v-model:checked-row-keys="checkedRowKeys"
            :columns="columns"
            :data="data"
            size="small"
            :flex-height="!appStore.isMobile"
            :loading="loading"
            remote
            :row-key="row => row.userId"
            :pagination="mobilePagination"
            class="sm:h-full"
          />
          <UserOperateModal
            v-model:visible="drawerVisible"
            :operate-type="operateType"
            :row-data="editingData"
            @submitted="getData"
          />
          <UserAuthRoleOperateModal v-model:visible="drawerVisibleRole" :user-id="userId" />
        </NCard>
      </div>
    </NGridItem>
  </NGrid>
</template>

<style scoped></style>
