<template>
  <el-dialog
    title="编辑用户"
    :model-value="visible"
    @update:model-value="$emit('update:visible', $event)"
    width="600px"
    :close-on-click-modal="false"
    append-to-body
    destroy-on-close
    :align-center="true"
    :fullscreen="false"
    @close="handleClose"
    class="user-edit-dialog"
  >
    <div class="dialog-content" style="padding: 20px; padding-bottom: 80px;height: 700px;overflow-y: auto;">
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
      <!-- 姓名和用户名 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="真实姓名" prop="realname">
            <el-input v-model="form.realname" placeholder="请输入真实姓名" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="用户名" prop="username">
            <el-input v-model="form.username" placeholder="请输入用户名" />
          </el-form-item>
        </el-col>
      </el-row>

      <!-- 密码和确认密码 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="密码" prop="password">
            <el-input
              v-model="form.password"
              type="password"
              placeholder="请输入密码"
              show-password
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="确认密码" prop="confirmPassword">
            <el-input
              v-model="form.confirmPassword"
              type="password"
              placeholder="请确认密码"
              show-password
            />
          </el-form-item>
        </el-col>
      </el-row>

      <!-- 邮箱 -->
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="form.email" placeholder="请输入邮箱" />
      </el-form-item>

      <!-- 用户组 -->
        <el-form-item label="用户组" prop="userGroup">
          <el-select v-model="userGroup" multiple placeholder="请选择">
            <el-option
              v-for="item in userGroupOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      <!-- 备注 -->
      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="form.remark"
          placeholder="请输入备注"
        />
      </el-form-item>

      <!-- 用户是否禁用 -->
        <div style="display: flex; justify-content: flex-end; width: 100%;">
          <el-form-item label="用户是否禁用">
              <el-switch
                v-model="form.isenable"
                :active-value="0"
                :inactive-value="1"
              />
          </el-form-item>
        </div>
      </el-form>

      <!-- 角色选择 -->
      <div class="component-wrapper">
        <RoleTransfer
          :roles="roles"
          :selectedRoles="selectedRoles"
          :searchRole="searchRole"
          @update:roles="val => roles = val"
          @update:selectedRoles="val => selectedRoles = val"
          @update:searchRole="val => searchRole = val"
        />
        <div v-if="isAdminUser" class="overlay-mask">
          <div class="mask-message">
            <el-alert
              title="超级管理员用户的角色不可修改"
              type="info"
              :closable="false"
              show-icon
            />
          </div>
        </div>
      </div>

      <!-- 权限设置 -->
      <div class="component-wrapper">
        <PermissionArea
          :permissionList="permissionList"
          :allPermissionsSelected="allPermissionsSelected"
          @update:allPermissionsSelected="val => allPermissionsSelected = val"
          @permission-change="handlePermissionChange"
          @sub-permission-change="handleSubPermissionChange"
        />
        <div v-if="isAdminUser" class="overlay-mask">
          <div class="mask-message">
            <el-alert
              title="超级管理员用户的权限不可修改"
              type="info"
              :closable="false"
              show-icon
            />
          </div>
        </div>
      </div>
      </div>
    <template #footer>
      <div class="dialog-footer">
        <div class="footer-buttons">
          <el-button @click="handleClose">取 消</el-button>
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch, getCurrentInstance } from 'vue'
import { query, initEdit, add } from '@/api/safetyManagement/userConfig.js'
import { queryAll as queryAllRole } from '@/api/safetyManagement/roleConfig.js'
import { queryAll as queryAllGroup } from '@/api/safetyManagement/groupConfig.js'
import { queryAll as queryAllMenu } from '@/api/safetyManagement/menuConfig.js'
import RoleTransfer from '@/components/RoleTransfer/index.vue'
import PermissionArea from '@/components/PermissionArea/index.vue'
import { encrypt } from '@/utils/sm4encrypt.js'
// 定义组件名称
defineOptions({
  name: 'UserEdit'
})

// 定义props和emit
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  formData: {
    type: Object,
    default: () => null
  }
})

const emit = defineEmits(['update:visible', 'success'])

// 表单引用
const formRef = ref(null)

// 响应式数据
const form = reactive({
  id: null,
  realname: '',
  username: '',
  password: '',
  confirmPassword: '',
  email: '',
  remark: '',
  isenable: 1,
  groupList: [],
  rolesList: [],
  menuList: []
})

const userGroup = ref([]) // 用户组
const userGroupOptions = ref([])
const searchRole = ref('')
const roles = ref([])
const selectedRoles = ref([])
const allPermissionsSelected = ref(false)
const permissionList = ref([])
const instance = getCurrentInstance()

// 判断是否为超级管理员用户（roleId = 1）
const isAdminUser = ref(false)

// 表单校验规则
const validatePassword = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  } else {
    if (form.confirmPassword !== '') {
      formRef.value.validateField('confirmPassword')
    }
    callback()
  }
}

const validateConfirmPassword = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请再次输入密码'))
  } else if (value !== form.password) {
    callback(new Error('两次输入密码不一致!'))
  } else {
    callback()
  }
}

const rules = {
  realname: [
    { required: true, message: '请输入真实姓名', trigger: 'blur' }
  ],
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, validator: validatePassword, trigger: 'blur' }
  ],
  confirmPassword: [
    { required: true, validator: validateConfirmPassword, trigger: 'blur' }
  ],
  email: [
    { required: false, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
  ]
}

// 监听visible变化
watch(() => props.visible, (val) => {
  if (val && props.formData && props.formData.id) {
    // 弹窗打开且有id时，拉取用户详情和相关数据
    initEditData(props.formData.id)
  } else {
    // 新增，只需查询角色、用户组、菜单权限
    Promise.all([
      queryAllRole(),
      queryAllGroup(),
      queryAllMenu()
    ]).then(([roleRes, groupRes, menuRes]) => {
      // 用户组
      userGroupOptions.value = (groupRes.data || []).map(g => ({ value: g.id, label: g.groupname }))
      // 角色
      roles.value = (roleRes.data || []).map(r => ({
        id: r.id,
        name: r.rolename || r.name || '',
        selected: false
      }))
      selectedRoles.value = []
      // 权限
      function mapMenu(menuArr) {
        return (menuArr || []).filter(item => item.type !== '3' || item.type === 1).map(item => {
          const hasChildren = Array.isArray(item.children) && item.children.length > 0
          let children = hasChildren ? mapMenu(item.children) : null
          return {
            id: item.id,
            name: item.type === '2'? '项目管理-'+item.name : item.name,
            selected: false,
            indeterminate: false,
            expanded: false,
            children
          }
        })
      }
      permissionList.value = mapMenu(menuRes.data)
    })
  }
})

const passwordOld = ref('')
// 初始化编辑数据
const initEditData = async (id) => {
  // 1. 查询用户详情
  const userRes = await initEdit({ userId: id })
  userGroup.value = userRes.data.groupList ? userRes.data.groupList.map(g => g.id) : []
  passwordOld.value = userGroup.value.password
  // 2. 查询角色、用户组、菜单权限
  const [roleRes, groupRes, menuRes] = await Promise.all([
    queryAllRole(),
    queryAllGroup(),
    queryAllMenu()
  ])
  // 3. 数据匹配
  Object.assign(form, {
    ...userRes.data,
    confirmPassword: userRes.data.password
  })
  // 用户组
  userGroupOptions.value = (groupRes.data || []).map(g => ({ value: g.id, label: g.groupname }))
  // 是否是超管
  isAdminUser.value = userRes.data.rolesList.some(role => role.id === '1')
  // 未选中角色
  roles.value = roleRes.data
    .filter(r => !(userRes.data.rolesList.map(m => m.id) || []).includes(r.id))
    .map(r => ({
      id: r.id,
      name: r.rolename || r.name || ''
    }))
  // 选中的角色
  selectedRoles.value = roleRes.data
    .filter(r => (userRes.data.rolesList.map(m => m.id) || []).includes(r.id))
    .map(r => ({
      id: r.id,
      name: r.rolename || r.name || ''
    }))
  // 权限
  function mapMenu(menuArr, selectedIds = []) {
    return (menuArr || []).filter(item => item.type !== '3' || item.type === 1).map(item => {
      const hasChildren = Array.isArray(item.children) && item.children.length > 0
      let children = hasChildren ? mapMenu(item.children, selectedIds) : null
      let selected = selectedIds.includes(item.id)
      let indeterminate = false
      if (hasChildren) {
        const selectedCount = children.filter(c => c.selected).length
        if (selectedCount === 0) {
          selected = false
          indeterminate = false
        } else if (selectedCount === children.length) {
          selected = true
          indeterminate = false
        } else {
          selected = false
          indeterminate = true
        }
      }
      return {
        id: item.id,
        name: item.type === '2'? '项目管理-'+item.name : item.name,
        selected,
        indeterminate,
        expanded: false,
        children
      }
    })
  }
  permissionList.value = mapMenu(menuRes.data, userRes.data.menuList ? userRes.data.menuList.map(m => m.id) : [])
}

// 关闭弹窗
const handleClose = () => {
  emit('update:visible', false)
  formRef.value?.resetFields()
  Object.assign(form, {
    realname: '',
    username: '',
    password: '',
    confirmPassword: '',
    email: '',
    userGroup: [],
    remark: '',
    isenable: 1
  })
}

// 提交表单
const handleSubmit = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      // 提交表单逻辑
      const params = { ...form }

      // 选中的角色和分组和权限
      params.rolesList = selectedRoles.value.map(r => ({id :r.id}))
      params.groupList = userGroup.value.map(g => ({ id: g }))
      const selectedMenuIds = []
      function collectSelectedMenus(menus) {
        menus.forEach(menu => {
          if (menu.selected) {
            selectedMenuIds.push(menu.id)
          }
          if (menu.children && menu.children.length > 0) {
            collectSelectedMenus(menu.children)
          }
        })
      }
      collectSelectedMenus(permissionList.value)
      params.menuList = selectedMenuIds.map(id => ({ id }))
      
      console.log('submit form', params)
      // 新增用户时，密码加密
      if (!params.id) {
        params.password = encrypt(params.password)
      }else {
        const change =  passwordOld.value !== params.password
        params.password = encrypt(params.password)
      }
      add(params).then(res => {
        if (res.code === 'POP_00014') {
          instance.appContext.config.globalProperties.$modal.msgSuccess('保存成功')
          emit('success')
          handleClose()
        } else {
          instance.appContext.config.globalProperties.$modal.msgError(res.msg || '保存失败')
        }
      }).catch(() => {
        instance.appContext.config.globalProperties.$modal.msgError('保存异常')
      })
      // 调用接口保存数据
      emit('success')
      handleClose()
    }
  })
}

// 处理权限选择
const handlePermissionChange = (item, val) => {
  item.selected = val
  item.indeterminate = false // 清除半选状态
  if (item.children) {
    item.children.forEach(child => {
      child.selected = val
    })
  }
  checkAllPermissionsStatus()
}

const handleSubPermissionChange = (parent, child, val) => {
  child.selected = val
  // 检查父级状态
  if (parent.children) {
    // 如果所有子项都选中，父级完全选中
    const allSelected = parent.children.every(c => c.selected)
    // 如果部分子项选中，父级半选
    const someSelected = parent.children.some(c => c.selected)
    
    parent.selected = allSelected
    parent.indeterminate = !allSelected && someSelected
  }
  checkAllPermissionsStatus()
}

const checkAllPermissionsStatus = () => {
  allPermissionsSelected.value = permissionList.value.every(item => {
    if (item.children) {
      return item.selected && item.children.every(child => child.selected)
    }
    return item.selected
  })
}
</script>

<style lang="scss" scoped>
.role-transfer {
  display: flex;
  align-items: flex-start;
  gap: 10px;

  .transfer-list {
    flex: 1;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    height: 300px;
    display: flex;
    flex-direction: column;
    width: 310px;

    .transfer-header {
      padding: 8px 12px;
      border-bottom: 1px solid #dcdfe6;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: #f5f7fa;
        .select-all-action {
          color: #409EFF;
          cursor: pointer;
          font-size: 14px;
          margin-left: 10px;
          user-select: none;
          transition: color 0.2s;
          &:hover {
            color: #66b1ff;
            cursor: pointer;
          }
        }
    }

    .role-list, .selected-list {
      flex: 1;
      overflow-y: auto;
      padding: 6px 0;
    }

    .role-item {
      padding: 6px 12px;
      cursor: pointer;

      &:hover {
        background-color: #f5f7fa;
      }
    }
  }

  .transfer-operation {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 10px 0;
  }
}

.permission-area {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  width: 100%;
  display: flex;
  flex-direction: column;
  height: 350px;
  overflow-y: auto;

  .all-select {
    padding: 2px 12px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #dcdfe6;
  }

  .permission-list {
    padding: 12px;

    .permission-item {
      border-bottom: 1px solid #ebeef5;
      
      &:last-child {
        border-bottom: none;
      }

      .permission-header {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        padding: 5px 0;
        cursor: pointer;
        gap: 12px;
        .left {
          display: flex;
          align-items: center;
          gap: 8px;
        }
      }
      .sub-permissions {
        padding: 5px 0 5px 32px;
        display: flex;
        flex-direction: column;
        gap: 12px;
        background-color: #f8f9fb;
        border-top: 1px solid #ebeef5;
        .el-checkbox {
          margin-left: 0 !important;
        }
      }
    }
  }
}

:deep(.el-transfer-panel) {
  width: 100%;
}

.user-edit-dialog {
  :deep(.el-dialog) {
    display: flex;
    flex-direction: column;
    margin: 0 auto !important;
    max-height: 90vh;
    position: relative;

    .el-dialog__body {
      flex: 1;
      overflow: hidden;
      padding: 0;
    }

    .dialog-content {
      height: 100%;
      overflow-y: auto;
      padding: 20px;
      padding-bottom: 80px;
    }
  }
}

.dialog-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 20px;
  background-color: #fff;
  border-top: 1px solid #dcdfe6;
  z-index: 9999;
  
  .footer-buttons {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
  }
}

.permission-header .expand-icon-placeholder {
  display: inline-block;
  min-width: 22px;
  height: 22px;
  vertical-align: middle;
}
.permission-header .expand-icon {
  min-width: 22px;
  text-align: center;
  display: inline-flex;
}

.component-wrapper {
  position: relative;
}

.overlay-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10;
}

.mask-message {
  padding: 10px;
  border-radius: 4px;
  width: 80%;
  max-width: 400px;
}
</style>
