<template>
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    width="50%"
    :show-close="false"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :before-close="handleBeforeClose"
    center
  >
    <el-form>
      <el-form-item class="role-form-item">
        <el-radio-group v-model="radio" class="role-radio-group" @change="handleChangeRole">
          <template v-for="(roles, groupName) in allRoleGroups" :key="groupName">
            <div class="role-group">
              <el-divider>{{ groupName }}</el-divider>
              <el-radio-button
                v-for="item in roles"
                :key="item.roleCode"
                :label="item.roleCode"
              >
                {{ item.roleName }}
              </el-radio-button>
            </div>
          </template>
        </el-radio-group>
      </el-form-item>
    </el-form>

    <template v-if="!requireSelectToClose" #footer>
      <el-button @click="handleFooterClose">关 闭</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, toRef } from 'vue'
import { listAllRole } from '/@/api/admin/role'
import { Local } from '/@/utils/storage'
import { useMessage } from '/@/hooks/message'

/** 弹框标题，如「角色切换」「登录角色选择」 */
const props = withDefaults(
  defineProps<{ title?: string; requireSelectToClose?: boolean }>(),
  { title: '角色切换', requireSelectToClose: false }
)
const dialogTitle = computed(() => props.title)

const visible = ref(false)
const radio = ref('')
/** 按分组名分组的角色列表：{ "未分组": [{ roleId, roleName, roleCode, ... }], ... } */
const allRoleGroups = ref<Record<string, any[]>>({})
const requireSelectToClose = toRef(props, 'requireSelectToClose')

const open = () => {
  if (visible.value) return
  visible.value = true
  listAllRole().then((res) => {
    allRoleGroups.value = res.data && typeof res.data === 'object' && !Array.isArray(res.data)
      ? res.data
      : { '未分组': Array.isArray(res.data) ? res.data : [] }
    radio.value = Local.get('roleCode')
  })
}

/** 根据 roleCode 从分组数据中查找角色 */
const findRoleByCode = (code: string) => {
  for (const roles of Object.values(allRoleGroups.value)) {
    if (!Array.isArray(roles)) continue
    const found = roles.find((r: any) => r.roleCode === code)
    if (found) return found
  }
  return null
}

const canClose = () => {
  if (!radio.value) {
    useMessage().warning('请选择一个角色')
    return false
  }
  return true
}

const handleBeforeClose = (done: () => void) => {
  if (requireSelectToClose.value) {
    useMessage().warning('请先选择登录角色')
    return
  }
  if (!canClose()) return
  done()
}

const handleFooterClose = () => {
  if (!canClose()) return
  visible.value = false
}

const handleChangeRole = (label: string) => {
  const obj = findRoleByCode(label)
  if (!obj) return
  Local.set('roleCode', obj.roleCode)
  Local.set('roleName', obj.roleName)
  Local.set('roleId', obj.roleId)
  useMessage().success('操作成功')
  setTimeout(() => {
    // 切换角色后统一回到首页，避免停留在诸如 jsonflow/run-job/do-job 等内部路由
    window.location.hash = '#/'
    window.location.reload()
  }, 500)
}

defineExpose({
  open
})
</script>

<style scoped lang="scss">
.role-form-item {
  :deep(.el-form-item__content) {
    flex-wrap: wrap;
  }
}
.role-group {
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}
.group-name {
  font-size: 13px;
  color: var(--el-text-color-secondary);
  margin-bottom: 6px;
}
.role-radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;

  /* 每个按钮独立边框，换行后左侧也有边线 */
  :deep(.el-radio-button) {
    margin: 0;
  }
  :deep(.el-radio-button__inner) {
    border-radius: 6px !important;
    border: 1px solid var(--el-border-color) !important;
    margin-left: 0 !important;
  }
  :deep(.el-radio-button.is-active .el-radio-button__inner) {
    border-color: var(--el-color-primary) !important;
  }
}
</style>