<template>
  <doc-alert title="用户体系" url="https://doc.iocoder.cn/user-center/" />
  <doc-alert title="三方登陆" url="https://doc.iocoder.cn/social-user/" />
  <doc-alert title="Excel 导入导出" url="https://doc.iocoder.cn/excel-import-and-export/" />

  <div class="user-management-container" :gutter="12" :class="{ 'no-gap': isTreeCollapsed }">
    <!-- 左侧部门树 -->
    <div
      class="dept-tree-col"
      :class="{ 'tree-collapsed': isTreeCollapsed }"
      :style="{ height: tableHeight + 'px' }"
    >
      <DeptTree @node-click="handleDeptNodeClick" />
    </div>
    <div class="table-col">
      <div class="table-wrap">
        <!-- 表格部分使用TableList组件 -->
        <TableList ref="tableListRef" :config="tableListConfig" />
        <!-- 悬浮切换按钮 -->
        <div
          class="tree-toggle-btn"
          :class="{ collapsed: isTreeCollapsed }"
          @click="toggleTreeCollapse"
          :style="{
            top: tableHeight / 2 + 'px',
            left: buttonLeftPosition + 'px'
          }"
        >
          <Icon :icon="isTreeCollapsed ? 'ep:arrow-right' : 'ep:arrow-left'" />
        </div>
      </div>
    </div>
  </div>

  <!-- 添加或修改用户对话框 -->
  <UserForm ref="formRef" @success="getList" />
  <!-- 用户导入对话框 -->
  <UserImportForm ref="importFormRef" @success="getList" />
  <!-- 分配角色 -->
  <UserAssignRoleForm ref="assignRoleFormRef" @success="getList" />
</template>
<script lang="ts" setup>
import { computed, h as createElement, ref, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useAppStore } from '@/store/modules/app'
import { checkPermi } from '@/utils/permission'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { CommonStatusEnum } from '@/utils/constants'
import * as UserApi from '@/api/system/user'
import UserForm from './UserForm.vue'
import UserImportForm from './UserImportForm.vue'
import UserAssignRoleForm from './UserAssignRoleForm.vue'
import DeptTree from './DeptTree.vue'
import { ElSwitch } from 'element-plus'
import TableList from '@/components/TableList/index.vue'
import type { TableListConfig } from '@/components/TableList/types'

defineOptions({ name: 'SystemUser' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const appStore = useAppStore()
const isCollapsed = computed(() => appStore.getCollapse)
// TableList组件内部管理这些状态，这里不再需要
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  username: undefined,
  mobile: undefined,
  status: undefined,
  deptId: undefined,
  nickname: undefined,
  createTime: []
})
const queryFormRef = ref() // 搜索的表单
const checkedIds = ref<number[]>([]) // 选中的用户ID数组
const tableListRef = ref<InstanceType<typeof TableList>>() // TableList组件引用

// 高度相关状态
const tableHeight = ref(600) // 表格高度
const isTreeCollapsed = ref(false) // 左侧树是否收起
const buttonLeftPosition = ref(0) // 按钮左位置

// TableList配置
const tableListConfig = computed(
  (): TableListConfig => ({
    searchForm: {
      items: [
        {
          field: 'username',
          label: '账号',
          type: 'input',
          placeholder: '请输入账号'
        },
        {
          field: 'nickname',
          label: '姓名',
          type: 'input',
          placeholder: '请输入姓名'
        },
        {
          field: 'mobile',
          label: '手机号码',
          type: 'input',
          placeholder: '请输入手机号码'
        },
        {
          field: 'status',
          label: '状态',
          type: 'select',
          placeholder: '请选择用户状态',
          options: getIntDictOptions(DICT_TYPE.COMMON_STATUS)
        },
        {
          field: 'createTime',
          label: '创建时间',
          type: 'date-range',
          valueFormat: 'YYYY-MM-DD HH:mm:ss',
          defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
        }
      ]
    },
    table: {
      columns: [
        // { prop: 'id', label: '用户编号', align: 'center' },
        { prop: 'username', label: '账号', align: 'center', showOverflowTooltip: true },
        { prop: 'nickname', label: '姓名', align: 'center', showOverflowTooltip: true },
        { prop: 'deptName', label: '部门', align: 'center', showOverflowTooltip: true },
        { prop: 'mobile', label: '手机号码', align: 'center', width: 120 },
        {
          prop: 'status',
          label: '状态',
          align: 'center',
          render: (passedH: any, { row }: { row: any }) => {
            const h = passedH || createElement
            return h('div', { style: 'text-align: center' }, [
              h(ElSwitch, {
                modelValue: row.status,
                activeValue: 0,
                inactiveValue: 1,
                onChange: () => handleStatusChange(row),
                disabled: !checkPermi(['system:user:update']),
                size: 'small'
              })
            ])
          }
        },
        {
          prop: 'creatorName',
          label: '创建人',
          align: 'center',
          width: 180,
        },
        {
          prop: 'createTime',
          label: '创建时间',
          align: 'center',
          width: 180,
          formatter: (row: any) => dateFormatter({}, {}, row.createTime)
        },
        {
          prop: 'updaterName',
          label: '修改人',
          align: 'center',
          width: 180,
        },
        {
          prop: 'updateTime',
          label: '修改时间',
          align: 'center',
          width: 180,
          formatter: (row: any) => dateFormatter({}, {}, row.updateTime)
        },
      ],
      actions: [
        {
          label: '修改',
          type: 'primary',
          link: true,
          show: (row: any) => checkPermi(['system:user:update']),
          handler: (row: any) => openForm('update', row.id)
        },
        {
          label: '删除',
          type: 'danger',
          link: true,
          show: (row: any) => checkPermi(['system:user:delete']),
          handler: (row: any) => handleDelete(row.id)
        },
        {
          label: '重置密码',
          type: 'warning',
          link: true,
          show: (row: any) => checkPermi(['system:user:update-password']),
          handler: (row: any) => handleResetPwd(row)
        },
        {
          label: '分配角色',
          type: 'primary',
          link: true,
          show: (row: any) => checkPermi(['system:permission:assign-user-role']),
          handler: (row: any) => handleRole(row)
        }
      ],
      selection: true
    },
    actions: [
      {
        label: '新增',
        type: 'primary',
        plain: false,
        icon: 'ep:plus',
        show: () => checkPermi(['system:user:create']),
        handler: () => openForm('create')
      },
      {
        label: '批量删除',
        type: 'danger',
        plain: false,
        disabled: () => checkedIds.value.length === 0,
        icon: 'ep:delete',
        show: () => checkPermi(['system:user:delete']),
        handler: handleDeleteBatch
      },
      // {
      //   label: '导入',
      //   type: 'default',
      //   plain: true,
      //   icon: 'ep:upload',
      //   show: () => checkPermi(['system:user:import']),
      //   handler: handleImport
      // },
      // {
      //   label: '同步人事数据',
      //   type: 'default',
      //   plain: true,
      //   icon: 'ep:refresh',
      //   handler: refreshData
      // }
    ],
    api: {
      getList: (params: any) => UserApi.getUserPage(params)
    },
    settings: {
      refresh: true,
      download: false,
      // download: async () => {
      //   try {
      //     exportLoading.value = true
      //     const currentParams = tableListRef.value?.queryParams || queryParams
      //     const data = await UserApi.exportUser(currentParams)
      //     download.excel(data, '用户数据.xls')
      //   } catch {
      //   } finally {
      //     exportLoading.value = false
      //   }
      // },
      print: true,
      size: true,
      columns: true,
      fullscreen: true
    },
    queryParams,
    onSelectionChange: (selection: any[]) => {
      checkedIds.value = selection.map((row) => row.id)
    }
  })
)

/** 查询列表 - 由TableList组件内部管理，这里只提供方法供其他组件调用 */
const getList = () => {
  tableListRef.value?.getList()
}

/** 搜索按钮操作 - TableList组件已处理 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 - TableList组件已处理 */
const resetQuery = () => {
  console.log('重置按钮操作')
  // TableList组件会调用tableListConfig.onReset
  // 这里只需要恢复部门选择状态
  queryParams.deptId = undefined
  getList()
}

/** 处理部门被点击 */
const handleDeptNodeClick = async (row: any) => {
  // 直接更新TableList组件内部的queryParams
  const deptId = row === undefined ? undefined : row.id
  tableListRef.value?.updateQueryParams({ deptId })

  // 调用TableList组件的搜索方法
  tableListRef.value?.handleSearch()
}

/** 切换左侧树显示/隐藏 */
const toggleTreeCollapse = () => {
  isTreeCollapsed.value = !isTreeCollapsed.value

  // 等待DOM更新后重新计算高度和按钮位置
  nextTick(() => {
    // 使用多次延时确保DOM完全更新
    setTimeout(() => {
      calculateTableHeight()
    }, 50)
    setTimeout(() => {
      calculateTableHeight()
    }, 200)
    setTimeout(() => {
      calculateTableHeight()
    }, 500)
  })
}

/** 计算表格高度和按钮位置 */
const calculateTableHeight = () => {
  nextTick(() => {
    const tableEl = document.querySelector('.table-wrap')
    if (tableEl) {
      tableHeight.value = tableEl.offsetHeight
    }

    // 重新计算按钮位置
    const tableWrapEl = document.querySelector('.table-wrap')
    const tableColEl = document.querySelector('.table-col')

    if (tableWrapEl && tableColEl) {
      if (isTreeCollapsed.value) {
        // 左侧树隐藏时，按钮在表格容器内左侧5px
        buttonLeftPosition.value = 5
      } else {
        // 左侧树显示时，按钮在表格列容器的最左边缘
        const tableColRect = tableColEl.getBoundingClientRect()
        const tableWrapRect = tableWrapEl.getBoundingClientRect()
        const relativeLeft = tableColRect.left - tableWrapRect.left
        buttonLeftPosition.value = Math.max(relativeLeft - 5, 0)
      }
    } else {
      // 回退方案
      buttonLeftPosition.value = isTreeCollapsed.value ? 5 : 0
    }
  })
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}

/** 用户导入 */
const importFormRef = ref()
const handleImport = () => {
  importFormRef.value.open()
}

/** 修改用户状态 */
const handleStatusChange = async (row: UserApi.UserVO) => {
  console.log('----row-----', row)
  if (row.username && (row.status !== null || row.status !== undefined)) {
    const oldStatus = row.status
    try {
      // 修改状态的二次确认
      const text = row.status == CommonStatusEnum.ENABLE ? '停用' : '启用'
      await message.confirm('确认要"' + text + '""' + row.username + '"用户吗?')
      const changeStatusMap = {
        1: 0,
        0: 1
      }
      // 发起修改状态
      await UserApi.updateUserStatus(row.id, changeStatusMap[row.status])
      // 刷新列表
      await getList()
    } catch {
      // 取消后，进行恢复按钮
      row.status = oldStatus
      // 刷新列表
      // await getList()
    }
  }
}

/** 导出按钮操作 */
const exportLoading = ref(false)
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await UserApi.exportUser(queryParams)
    download.excel(data, '用户数据.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 操作分发 */
const handleCommand = (command: string, row: UserApi.UserVO) => {
  switch (command) {
    case 'handleDelete':
      handleDelete(row.id)
      break
    case 'handleResetPwd':
      handleResetPwd(row)
      break
    case 'handleRole':
      handleRole(row)
      break
    default:
      break
  }
}

/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await UserApi.deleteUser(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

/** 批量删除按钮操作 - 由TableList组件处理选择逻辑 */

const handleDeleteBatch = async () => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起批量删除
    await UserApi.deleteUserList(checkedIds.value)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

const refreshData = async () => {
  try {
    await message.confirm('确认要同步人事数据么？')
    await UserApi.getSynchronizeUser()
    message.success('同步成功')
    // 刷新列表
    await getList()
  } catch {}
}

/** 重置密码 */
const handleResetPwd = async (row: UserApi.UserVO) => {
  try {
  ElMessageBox.prompt('请输入"' + row.username + '"的新密码',  t('common.reminder'), {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern:
     /^.{8,}$/,
    inputErrorMessage: '密码长度不能少于8位',
  })
    .then(async({ value }) => {
      const password = value
      await UserApi.resetUserPassword(row.id, password)
      message.success('修改成功，新密码是：' + password)
    })
    .catch(() => {
    })
  } catch {}
}

/** 分配角色 */
const assignRoleFormRef = ref()
const handleRole = (row: UserApi.UserVO) => {
  assignRoleFormRef.value.open(row)
}

/** 初始化 */
onMounted(async () => {
  await getList()

  // 初始计算高度和按钮位置
  setTimeout(() => {
    calculateTableHeight()
  }, 800) // 给表格渲染更多时间

  setTimeout(() => {
    calculateTableHeight()
  }, 1500) // 二次计算确保准确

  // 监听窗口大小变化，重新计算高度
  window.addEventListener('resize', () => {
    setTimeout(calculateTableHeight, 300)
  })
})

// 监听isTreeCollapsed变化，重新计算高度和按钮位置
watch(isCollapsed, () => {
  nextTick(() => {
    setTimeout(() => {
      calculateTableHeight()
    }, 200)
  })
})
</script>

<style scoped>
.user-management-container {
  position: relative;
  display: flex;
  gap: 12px;
  width: 100%;
}
.no-gap {
  gap: 0 !important;
}

.dept-tree-col {
  flex: 0 0 16.666667%; /* 对应原来span=4的宽度 (4/24) */
  transition:
    flex 0.3s ease,
    opacity 0.3s ease,
    margin-right 0.3s ease;
  position: relative;
  min-width: 0;
  min-height: 600px;
  overflow: hidden;
  border-radius: 8px;
  background-color: #fff;
  box-shadow:
    0 1px 2px 0 rgba(0, 0, 0, 0.03),
    0 1px 6px -1px rgba(0, 0, 0, 0.02),
    0 2px 4px 0 rgba(0, 0, 0, 0.02);
  padding: 10px;
}

.dept-tree-col.tree-collapsed {
  flex: 0 0 0;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  padding: 0;
}

.dept-tree-content {
  min-height: 600px;
  transition: height 0.3s ease;
}

.table-col {
  flex: 1;
  transition: flex 0.3s ease;
  min-width: 0;
}

.table-wrap {
  position: relative;
}

.tree-toggle-btn {
  position: absolute;
  transform: translateX(-50%);
  width: 30px;
  height: 30px;
  background-color: #fff;
  color: rgba(0, 0, 0, 0.88);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  transition: all 0.3s ease;
  border: 2px solid white;
}

.tree-toggle-btn:hover {
  transform: translateX(-50%) scale(1.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

/* 响应式适配 */
@media (max-width: 400px) {
  .user-management-container {
    flex-direction: column;
  }

  .dept-tree-col {
    flex: 0 0 auto;
    width: 100%;
  }

  .dept-tree-col.tree-collapsed {
    height: 0;
    margin-right: 0;
    margin-bottom: 0;
  }

  .table-col {
    flex: 1;
  }

  .tree-toggle-btn {
    left: -10px;
    width: 25px;
    height: 25px;
  }

  .tree-toggle-btn.collapsed {
    left: 10px;
  }
}

/* 平滑过渡效果 */
.dept-tree-col :deep(.content-wrap) {
  transition: all 0.3s ease;
}

.table-col :deep(.content-wrap) {
  transition: all 0.3s ease;
}
</style>
