<script lang="ts" setup>
import { h, ref, watch, onMounted } from 'vue';
import type { DataTableColumns, DataTableRowKey, RowData } from 'naive-ui';
import {
  NButton,
  NCard,
  NDataTable,
  NDialog,
  NForm,
  NFormItem,
  NInput,
  NModal,
  NPagination,
  NRadio,
  NSpace,
  NSpin,
  useDialog,
  useMessage
} from 'naive-ui';
import { Glasses, GlassesOutline } from '@vicons/ionicons5';
import { api_addUser, api_deleteUser, api_getDepList, api_getPosList, api_getRoleList, api_getUserById, api_updateUser, api_userPageGet, api_exportUserData, api_putPassword } from '@/api/index';
import { userRules,passwordRules } from "@/rules/rules";
import { start } from 'nprogress';
import { keys } from 'localforage';

const message = useMessage();

// 常量和响应式数据
const tableData = ref([]);

const createModal = ref(false);
const passwordModal = ref(false)
const passShow = ref(false);
const pageSizes = ref([10, 20, 50, 100]);
const show = ref(false);
const range = ref<any>()
const ids = ref<DataTableRowKey[]>([]);
const pageData = ref({
  pageNum: 1,
  pageSize: 10,
  total: 10
})
const title = ref('新增用户')
const roleOptions = ref([]);
const posOptions = ref([]);
const depOptions = ref([]);

// 数据绑定
const formData = ref({
  id: '',
  name: '',
  username: '',
  password: '',
  phone: '',
  roleId: undefined,
  depId: '',
  posId: undefined
});
const serarchData = ref({
  pageNum: pageData.value.pageNum,
  pageSize: pageData.value.pageSize,
  username: '',
  depname: '',
  startTime: '',
  endTime: ''
})
const posData = ref({
  id: '',
  password: ''
})

// 表格列配置
const userColumn = [
  {
    type: 'selection' as const,
    width: 50
  },
  {
    title: '排序',
    key: 'id',
    align: 'center',
    width: 80
  },
  {
    title: '用户名',
    key: 'username',
    align: 'center',
    minWidth: 200,
    treeConfig: {
      indent: 20,
      expandable: (row: any) => Boolean(row.children) && row.children.length > 0
    },
    render(row: any) {
      return h('span', null, row.username);
    }
  },
  {
    title: '用户姓名',
    key: 'name',
    align: 'center',
    minWidth: 100
  },
  {
    title: '角色',
    key: 'roleName',
    align: 'center',
    minWidth: 100
  },
  {
    title: '部门',
    key: 'depName',
    align: 'center',
    minWidth: 100
  },
  {
    title: '岗位',
    key: 'posName',
    align: 'center',
    minWidth: 100
  },
  {
    title: '手机号',
    key: 'phone',
    align: 'center',
    minWidth: 120
  },
  {
    title: '创建日期',
    key: 'createTime',
    align: 'center',
    minWidth: 180
  },
  {
    title: '操作',
    key: 'actions',
    align: 'center',
    minWidth: 120,
    render(row: any) {
      // 改用Vue推荐的方式创建元素
      return h(NSpace, { justify: 'center' }, [
        h(
          NButton,
          {
            size: 'small',
            style: {
              color: '#eee',
              backgroundColor: '#2196ed',
              borderColor: '#2196ed',
              borderRadius: '4px',
              padding: '4px 12px'
            },
            onClick: () => handleEdit(row)
          },
          [
            h('img', {
              src: '/src/assets/bianji.png',
              alt: '编辑',
              style: {
                width: '10px',
                height: '10px',
                marginRight: '5px'
              }
            }),
            '编辑'
          ]
        ),
        h(
          NButton,
          {
            size: 'small',
            style: {
              color: '#eee',
              backgroundColor: '#2196ed',
              borderColor: '#2196ed',
              borderRadius: '4px',
              padding: '4px 12px'
            },
            onClick: () => putPossword(row)
          },
          [
            h('img', {
              src: '/src/assets/bianji.png',
              alt: '修改密码',
              style: {
                width: '10px',
                height: '10px',
                marginRight: '5px'
              }
            }),
            '修改密码'
          ]
        ),
        h(
          NButton,
          {
            size: 'small',
            style: {
              color: '#eee',
              backgroundColor: '#f16255',
              borderColor: '#f16255',
              borderRadius: '4px',
              padding: '4px 12px'
            },
            onClick: () => handleDelete(row)
          },
          [
            h('img', {
              src: '/src/assets/delete.png',
              alt: '删除',
              style: {
                width: '10px',
                height: '10px',
                marginRight: '5px'
              }
            }),
            '删除'
          ]
        )
      ]);
    }
  }
];


// 添加表单校验相关的引用和方法
const formRef = ref<InstanceType<typeof NForm>>();

function handleSubmit() {
  if (!formRef.value) return;
  formRef.value.validate(async errors => {
    if (!errors) {
      let res = null;
      if(formData.value.id){
        //修改
         res = await api_updateUser(formData.value)
      }else{
        //新增
         res = await api_addUser(formData.value)
      }

      if(res.data.code == 200){
        message.success('操作成功')
        search()
        createModal.value = false;
      }else{
        message.error(res.data.msg)
      }
    } else {
      console.log('表单校验失败', errors);
    }
  });
}
// 修改密码
function posSubmit() {
  if (!formRef.value) return;
  formRef.value.validate(async errors => {
    if (!errors) {
      let res = null;

      res = await api_putPassword(posData.value);
      if(res.data.code == 200){
        message.success('修改成功')
        search()
        passwordModal.value = false;
        localStorage.removeItem('token');
        window.location.href = '/login';
      }else{
        message.error(res.data.msg)
      }
    } else {
      console.log('表单校验失败', errors);
    }
  });
}

function handleCheck(rowKeys: DataTableRowKey[]) {
  ids.value = rowKeys;
}

async function handleEdit(row: any) {
  title.value = '编辑用户'

  let res = await api_getUserById(row.id)

  formData.value = res.data.data;

  createModal.value = true;
  passShow.value = false;
}
const dialog = useDialog();

function handleDelete(row: any) {
  dialog.create({
    title: '提示',
    content: '确定删除数据？',
    positiveText: '确定',
    negativeText: '取消',
    positiveButtonProps: {
      type: 'primary' // 设置确定按钮为蓝色
    },
    showIcon: false, // 去掉感叹号图标
    onPositiveClick: async () => {
      // 用户确认删除后执行删除操作
      let res = await api_deleteUser(row.id);
      if(res.data.code == 200){
        search()
        message.success('删除成功')
      }else{
        message.error(res.data.msg)
      }
    }
  });
}
// 修改 密码
async function putPossword(row) {
  title.value = '修改密码'
  passwordModal.value = true;
  posData.value = {
    id: row.id,
    password: ''
  }
}

//  头部新增
function handleAdd() {
  title.value = '新增用户'
  // 重置表单数据
  formData.value = {
    id: '',
    name: '',
    username: '',
    password: '',
    phone: '',
    roleId: undefined,
    depId: '',
    posId: undefined
  };

  createModal.value = true;
  passShow.value = true
}
// 头部编辑
async function topCompile() {
  if (ids.value.length === 0) {
    message.error('请选择一个要编辑的用户');
  } else if (ids.value.length > 1) {
    message.error('只能编辑一个用户');
  } else {
    title.value = '编辑用户'
    let res = await api_getUserById(ids.value[0])

    createModal.value = true;
    passShow.value = false;
    if(res.data.code == 200){
      formData.value = res.data.data
    }else{
      message.error(res.data.msg)
    }

  }
}
// 头部删除
async function topDelete() {
  if (ids.value == null || ids.value.length == 0) {
    message.error('请选择要删除的用户');
  } else {
    dialog.create({
      title: '提示',
      content: '确定删除数据？',
      positiveText: '确定',
      negativeText: '取消',
      positiveButtonProps: {
        type: 'primary' // 设置确定按钮为蓝色
      },
      showIcon: false, // 去掉感叹号图标
      onPositiveClick: async () => {
        let id = ids.value.join(',')
        // 用户确认删除后执行删除操作
        let res = await api_deleteUser(id);
        if (res.data.code == 200) {
          search()
          message.success('删除成功')
        } else {
          message.error(res.data.msg)
        }
      }
    });
  }
}
// 头部导出
async function topDerive() {
  if(ids.value == null || ids.value.length == 0){
    message.error('请选择要导出的用户');
  }else{
    let id = ids.value.join(',')
    let res = await api_exportUserData(id);
    console.log(res);
    if(res.status == 200){
      let blob = res.data;
      let url = window.URL.createObjectURL(blob);
      let a = document.createElement('a');
      document.body.appendChild(a);
      a.href = url;
      a.download = '用户数据.xlsx';
      a.click();
      window.URL.revokeObjectURL(url);
      message.success('导出成功，请到下载目录查看')
    } else {
      message.error(res.msg)
    }
  }
}


function handleSearch() {
  search()
}

function watchTimeData(value: any) {
  serarchData.value.startTime = value[0];
  serarchData.value.endTime = value[1];
}

async function search() {
  let res = await api_userPageGet(serarchData.value);

  if (res.data.code == 200) {
    tableData.value = res.data.data.records;
    pageData.value.total = Number(res.data.data.total);
  } else {
    message.error(res.data.msg);
  }
}

function handleReset() {
  serarchData.value = {
    pageNum: pageData.value.pageNum,
    pageSize: pageData.value.pageSize,
    username: '',
    depname: '',
    startTime: '',
    endTime: ''
  }
  range.value = null

  search()
}

async function createAllData() {
  let posRes = await api_getPosList()
  if (posRes.data.code == 200) {
    posOptions.value = posRes.data.data
  } else {
    message.error(posRes.data.msg)
  }
  let roleRes = await api_getRoleList()

  if (roleRes.data.code == 200) {
    roleOptions.value = roleRes.data.data
  } else {
    message.error(posRes.data.msg)
  }

  let depRes = await api_getDepList()

  if (depRes.data.code == 200) {
    console.log(depRes.data.data.data[0].children);

    depOptions.value = depRes.data.data.data[0].children

  } else {
    message.error(posRes.data.msg)
  }
}

function handlePage() {
  serarchData.value.pageNum = pageData.value.pageNum
  search()
}

function handlePageSize() {
  serarchData.value.pageSize = pageData.value.pageSize
  search()
}

function handleclear() {
  serarchData.value.startTime = ''
  serarchData.value.endTime = ''
}

onMounted(() => {
  search()
  createAllData()
})
</script>

<template>
  <div id="DepartmentPage">
    <NModal v-model:show="createModal">
      <NCard :title="title" style="width: 600px" closable @close="createModal = false">
        <hr />
        <NForm ref="formRef" :rules="userRules" :model="formData" label-placement="left" label-width="auto"
          style="margin-left: 20px; margin-top: 20px">
          <NFormItem label="用户名" path="username" require-mark-placement="left" style="margin-right: 20px">
            <NInput v-model:value="formData.username" placeholder="请输入用户名" />
          </NFormItem>
          <NFormItem label="用户姓名" path="name" w require-mark-placement="left" style="margin-right: 20px">
            <NInput v-model:value="formData.name" placeholder="请输入用户姓名" />
          </NFormItem>
          <NFormItem label="部门名称" path="depId" require-mark-placement="left" style="margin-right: 20px">
            <n-tree-select v-model:value="formData.depId" :options="depOptions" placeholder="请选择部门" label-field="name"
              key-field="index" children-field="children" />
          </NFormItem>
          <NFormItem label="岗位名称" path="posId" require-mark-placement="left" style="margin-right: 20px">
            <n-select v-model:value="formData.posId" :options="posOptions" label-field="posName" value-field="id"
              placeholder="请选择岗位" />
          </NFormItem>
          <NFormItem label="角色名称" path="roleId" require-mark-placement="left" style="margin-right: 20px">
            <n-select v-model:value="formData.roleId" :options="roleOptions" label-field="roleName" value-field="id"
              placeholder="请选择角色" />
          </NFormItem>
          <NFormItem v-show="passShow" label="密码" path="password" require-mark-placement="left" style="margin-right: 20px">
            <NInput v-model:value="formData.password" type="password" show-password-on="click" placeholder="请输入密码" />
            <template #password-visible-icon>
              <NIcon :size="16" :component="GlassesOutline" />
            </template>
          </NFormItem>
          <NFormItem label="手机号" path="phone" require-mark-placement="left" style="margin-right: 20px">
            <NInput v-model:value="formData.phone" placeholder="请输入手机号" />
          </NFormItem>
        </NForm>

        <template #footer>
          <NSpace justify="end">
            <NButton @click="createModal = false">取消</NButton>
            <NButton type="primary" @click="handleSubmit">确认</NButton>
          </NSpace>
        </template>
      </NCard>
    </NModal>
<!-- 修改密码模态框 -->
    <NModal v-model:show="passwordModal">
      <NCard :title="title" style="width: 600px" closable @close="passwordModal = false">
        <hr />
        <NForm ref="formRef" :rules="passwordRules" :model="posData" label-placement="left" label-width="auto"
          style="margin-left: 20px; margin-top: 20px">
          <NFormItem label="密码" path="password" require-mark-placement="left" style="margin-right: 20px">
            <NInput v-model:value="posData.password" type="password" show-password-on="click" placeholder="请输入密码" />
            <template #password-visible-icon>
              <NIcon :size="16" :component="GlassesOutline" />
            </template>
          </NFormItem>
        </NForm>

        <template #footer>
          <NSpace justify="end">
            <NButton @click="passwordModal = false">取消</NButton>
            <NButton type="primary" @click="posSubmit">确认</NButton>
          </NSpace>
        </template>
      </NCard>
    </NModal>

    <div>
      <NSpin :show="show">
        <NCard size="medium">
          <div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center">
            <NSpace>
              <div>
                用户名
                <NInput v-model:value="serarchData.username" placeholder="请输入用户名"
                  style="width: 200px; margin-left: 10px" clearable="true" />
              </div>
              <div style="margin-left: 30px;">
                部门名称
                <NInput v-model:value="serarchData.depname" placeholder="请输入部门名称"
                  style="width: 200px; margin-left: 10px" clearable="true" />
              </div>
              <div style="display: flex; align-items: center; margin-left: 30px">
                <div>日期范围</div>
                <n-date-picker v-model:value="range" type="datetimerange" @update:value="watchTimeData" clearable
                  @clear="handleclear" style="margin-left: 10px" />
              </div>

              <NButton color="#2198f2" style="padding: 0px 17px; border-radius: 5px; margin-left: 20px"
                @click="handleSearch">
                查询
              </NButton>
              <NButton style="padding: 0px 17px; border-radius: 5px" @click="handleReset">重置</NButton>
            </NSpace>
          </div>
          <NSpace style="margin-bottom: 20px">
            <NButton color="#2198f2" style="padding: 0px 20px; border-radius: 5px" @click="handleAdd">
              <img src="@/assets/xinzeng.png" alt="" style="width: 10px; height: 10px; margin-right: 5px" />
              新增
            </NButton>
            <NButton color="#2198f2" style="padding: 0px 20px; border-radius: 5px" @click="topCompile">
              <img src="@/assets/bianji.png" alt="" style="width: 10px; height: 10px; margin-right: 5px" />
              编辑
            </NButton>
            <NButton color="#f36255" style="padding: 0px 20px; border-radius: 5px" @click="topDelete">
              <img src="@/assets/delete.png" alt="" style="width: 10px; height: 10px; margin-right: 5px" />
              删除
            </NButton>
            <NButton color="#ffbb01" style="padding: 0px 20px; border-radius: 5px" @click="topDerive">
              <img src="@/assets/daochu.png" alt="" style="width: 10px; height: 10px; margin-right: 5px" />
              导出
            </NButton>
          </NSpace>

          <NDataTable :row-key="row => row.id" :columns="userColumn" :data="tableData" :bordered="true"
            :pagination="false" tree-column-key="name" @update:checked-row-keys="handleCheck" />

          <div style="display: flex; justify-content: end; margin-top: 30px;">
            <ElPagination v-model:current-page="pageData.pageNum" v-model:page-size="pageData.pageSize"
              :page-sizes="[10, 20, 30, 40]" background="#2196f3" layout="sizes, prev, pager, next"
              :total="pageData.total" @size-change="handlePageSize" @current-change="handlePage" />
          </div>
        </NCard>
      </NSpin>
    </div>
  </div>
</template>

<style scoped>
:deep(.n-pagination .n-pagination-item.n-pagination-item--active) {
  background-color: #2196ed !important;
  color: white !important;
  border-color: #2196ed !important;
}
</style>
