<template>
  <div>
    <h2 class="text-xl font-bold text-gray-800 mb-6">權限管理</h2>

    <!-- Grant / Revoke -->
    <el-tabs v-model="activeTab" type="border-card" class="shadow-sm">
      <!-- Grant Tab -->
      <el-tab-pane label="Grant 授權" name="grant">
        <el-form
          ref="grantFormRef"
          :model="grantForm"
          :rules="grantRules"
          label-width="130px"
          class="max-w-xl mt-4"
          @submit.prevent="handleGrant"
        >
          <el-form-item label="Authentik Sub" prop="authentik_sub">
            <el-select v-model="grantForm.authentik_sub" filterable allow-create default-first-option placeholder="選擇會員或輸入 sub" style="width: 100%">
              <el-option v-for="m in members" :key="m.authentik_sub" :label="`${m.display_name || m.email || '(no-name)'} (${m.authentik_sub})`" :value="m.authentik_sub" />
            </el-select>
          </el-form-item>
          <el-form-item label="Email" prop="email">
            <el-input v-model="grantForm.email" placeholder="user@example.com" />
          </el-form-item>
          <el-form-item label="顯示名稱" prop="display_name">
            <el-input v-model="grantForm.display_name" placeholder="User Name" />
          </el-form-item>
          <el-form-item label="Scope 類型" prop="scope_type">
            <el-select v-model="grantForm.scope_type" placeholder="選擇 Scope 類型">
              <el-option label="Company" value="company" />
              <el-option label="Site" value="site" />
            </el-select>
          </el-form-item>
          <el-form-item label="Scope ID" prop="scope_id">
            <el-select v-model="grantForm.scope_id" placeholder="選擇 Scope ID" filterable style="width: 100%">
              <el-option v-for="s in grantScopeOptions" :key="s.value" :label="s.label" :value="s.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="系統" prop="system">
            <el-select v-model="grantForm.system" placeholder="選擇系統" filterable style="width: 100%">
              <el-option v-for="s in systems" :key="s.system_key" :label="`${s.name} (${s.system_key})`" :value="s.system_key" />
            </el-select>
          </el-form-item>
          <el-form-item label="模組（選填）" prop="module">
            <el-select v-model="grantForm.module" placeholder="系統層(留空) 或選模組" clearable filterable style="width: 100%">
              <el-option v-for="m in grantModuleOptions" :key="m.value" :label="m.label" :value="m.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="操作" prop="action">
            <el-select v-model="grantForm.action" filterable allow-create default-first-option style="width: 100%">
              <el-option v-for="a in actionOptions" :key="a" :label="a" :value="a" />
            </el-select>
          </el-form-item>

          <el-alert
            v-if="grantError"
            :title="grantError"
            type="error"
            show-icon
            :closable="false"
            class="mb-4"
          />
          <el-alert
            v-if="grantSuccess"
            :title="grantSuccess"
            type="success"
            show-icon
            :closable="false"
            class="mb-4"
          />

          <el-form-item>
            <el-button
              type="primary"
              native-type="submit"
              :loading="grantLoading"
            >
              Grant 授權
            </el-button>
            <el-button @click="resetGrant">清除</el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>

      <!-- Revoke Tab -->
      <el-tab-pane label="Revoke 撤銷" name="revoke">
        <el-form
          ref="revokeFormRef"
          :model="revokeForm"
          :rules="revokeRules"
          label-width="130px"
          class="max-w-xl mt-4"
          @submit.prevent="handleRevoke"
        >
          <el-form-item label="Authentik Sub" prop="authentik_sub">
            <el-select v-model="revokeForm.authentik_sub" filterable allow-create default-first-option placeholder="選擇會員或輸入 sub" style="width: 100%">
              <el-option v-for="m in members" :key="m.authentik_sub" :label="`${m.display_name || m.email || '(no-name)'} (${m.authentik_sub})`" :value="m.authentik_sub" />
            </el-select>
          </el-form-item>
          <el-form-item label="Scope 類型" prop="scope_type">
            <el-select v-model="revokeForm.scope_type" placeholder="選擇 Scope 類型">
              <el-option label="Company" value="company" />
              <el-option label="Site" value="site" />
            </el-select>
          </el-form-item>
          <el-form-item label="Scope ID" prop="scope_id">
            <el-select v-model="revokeForm.scope_id" placeholder="選擇 Scope ID" filterable style="width: 100%">
              <el-option v-for="s in revokeScopeOptions" :key="s.value" :label="s.label" :value="s.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="系統" prop="system">
            <el-select v-model="revokeForm.system" placeholder="選擇系統" filterable style="width: 100%">
              <el-option v-for="s in systems" :key="s.system_key" :label="`${s.name} (${s.system_key})`" :value="s.system_key" />
            </el-select>
          </el-form-item>
          <el-form-item label="模組（選填）" prop="module">
            <el-select v-model="revokeForm.module" placeholder="系統層(留空) 或選模組" clearable filterable style="width: 100%">
              <el-option v-for="m in revokeModuleOptions" :key="m.value" :label="m.label" :value="m.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="操作" prop="action">
            <el-select v-model="revokeForm.action" filterable allow-create default-first-option style="width: 100%">
              <el-option v-for="a in actionOptions" :key="a" :label="a" :value="a" />
            </el-select>
          </el-form-item>

          <el-alert
            v-if="revokeError"
            :title="revokeError"
            type="error"
            show-icon
            :closable="false"
            class="mb-4"
          />
          <el-alert
            v-if="revokeSuccess"
            :title="revokeSuccess"
            type="success"
            show-icon
            :closable="false"
            class="mb-4"
          />

          <el-form-item>
            <el-button
              type="danger"
              native-type="submit"
              :loading="revokeLoading"
            >
              Revoke 撤銷
            </el-button>
            <el-button @click="resetRevoke">清除</el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { usePermissionStore } from '@/stores/permission'
import { getSystems } from '@/api/systems'
import { getModules } from '@/api/modules'
import { getCompanies } from '@/api/companies'
import { getSites } from '@/api/sites'
import { getMembers } from '@/api/members'

const permissionStore = usePermissionStore()

const activeTab = ref('grant')
const systems = ref([])
const modules = ref([])
const companies = ref([])
const sites = ref([])
const members = ref([])
const actionOptions = ['view', 'edit', 'manage', 'admin']

// Grant
const grantFormRef = ref()
const grantLoading = ref(false)
const grantError = ref('')
const grantSuccess = ref('')

const grantForm = reactive({
  authentik_sub: '',
  email: '',
  display_name: '',
  scope_type: '',
  scope_id: '',
  system: '',
  module: '',
  action: ''
})

const grantModuleOptions = computed(() => {
  if (!grantForm.system) return []
  return modules.value
    .filter(m => m.system_key === grantForm.system && !m.module_key.endsWith('.__system__'))
    .map(m => ({
      value: m.module_key.startsWith(`${grantForm.system}.`)
        ? m.module_key.slice(grantForm.system.length + 1)
        : m.module_key,
      label: `${m.name} (${m.module_key})`
    }))
})

const grantScopeOptions = computed(() => {
  if (grantForm.scope_type === 'company') {
    return companies.value.map(c => ({ value: c.company_key, label: `${c.name} (${c.company_key})` }))
  }
  if (grantForm.scope_type === 'site') {
    return sites.value.map(s => ({ value: s.site_key, label: `${s.name} (${s.site_key})` }))
  }
  return []
})

const required = { required: true, message: '必填', trigger: 'blur' }
const grantRules = {
  authentik_sub: [required],
  email: [required],
  display_name: [required],
  scope_type: [required],
  scope_id: [required],
  system: [required],
  action: [required]
}

async function handleGrant() {
  const valid = await grantFormRef.value.validate().catch(() => false)
  if (!valid) return
  grantLoading.value = true
  grantError.value = ''
  grantSuccess.value = ''
  try {
    const result = await permissionStore.grant({ ...grantForm })
    grantSuccess.value = `授權成功（ID: ${result.permission_id}）`
    ElMessage.success('Grant 成功')
  } catch (err) {
    grantError.value = formatAdminError(err)
  } finally {
    grantLoading.value = false
  }
}

function resetGrant() {
  grantFormRef.value?.resetFields()
  grantError.value = ''
  grantSuccess.value = ''
}

// Revoke
const revokeFormRef = ref()
const revokeLoading = ref(false)
const revokeError = ref('')
const revokeSuccess = ref('')

const revokeForm = reactive({
  authentik_sub: '',
  scope_type: '',
  scope_id: '',
  system: '',
  module: '',
  action: ''
})

const revokeModuleOptions = computed(() => {
  if (!revokeForm.system) return []
  return modules.value
    .filter(m => m.system_key === revokeForm.system && !m.module_key.endsWith('.__system__'))
    .map(m => ({
      value: m.module_key.startsWith(`${revokeForm.system}.`)
        ? m.module_key.slice(revokeForm.system.length + 1)
        : m.module_key,
      label: `${m.name} (${m.module_key})`
    }))
})

const revokeScopeOptions = computed(() => {
  if (revokeForm.scope_type === 'company') {
    return companies.value.map(c => ({ value: c.company_key, label: `${c.name} (${c.company_key})` }))
  }
  if (revokeForm.scope_type === 'site') {
    return sites.value.map(s => ({ value: s.site_key, label: `${s.name} (${s.site_key})` }))
  }
  return []
})

const revokeRules = {
  authentik_sub: [required],
  scope_type: [required],
  scope_id: [required],
  system: [required],
  action: [required]
}

async function handleRevoke() {
  const valid = await revokeFormRef.value.validate().catch(() => false)
  if (!valid) return
  revokeLoading.value = true
  revokeError.value = ''
  revokeSuccess.value = ''
  try {
    const result = await permissionStore.revoke({ ...revokeForm })
    revokeSuccess.value = `撤銷成功（共刪除 ${result.deleted} 筆）`
    ElMessage.success('Revoke 成功')
  } catch (err) {
    revokeError.value = formatAdminError(err)
  } finally {
    revokeLoading.value = false
  }
}

function resetRevoke() {
  revokeFormRef.value?.resetFields()
  revokeError.value = ''
  revokeSuccess.value = ''
}

function formatAdminError(err) {
  const status = err.response?.status
  const detail = err.response?.data?.detail
  const map = {
    invalid_client: '無效的 Client Key',
    invalid_api_key: '無效的 API Key',
    client_expired: 'Client 已過期',
    origin_not_allowed: '來源 Origin 不允許',
    ip_not_allowed: 'IP 不在白名單',
    path_not_allowed: '路徑不允許',
    internal_secret_not_configured: '後端設定缺失（internal secret）',
    authentik_admin_not_configured: '後端設定缺失（authentik admin）',
    user_not_found: '找不到該使用者'
  }
  if (detail && map[detail]) return map[detail]
  if (detail) return `錯誤：${detail}`
  if (status === 401) return '認證失敗，請檢查 Client Key / API Key'
  if (status === 403) return '存取被拒（IP 或 Origin 限制）'
  if (status === 404) return '找不到該使用者'
  if (status === 503) return '後端設定不完整，請聯絡管理員'
  return '操作失敗，請稍後再試'
}

async function loadCatalogs() {
  const [systemsRes, modulesRes, companiesRes, sitesRes, membersRes] = await Promise.all([
    getSystems(),
    getModules(),
    getCompanies(),
    getSites(),
    getMembers()
  ])
  systems.value = systemsRes.data?.items || []
  modules.value = modulesRes.data?.items || []
  companies.value = companiesRes.data?.items || []
  sites.value = sitesRes.data?.items || []
  members.value = membersRes.data?.items || []
}

watch(() => grantForm.scope_type, () => { grantForm.scope_id = '' })
watch(() => grantForm.system, () => { grantForm.module = '' })
watch(() => revokeForm.scope_type, () => { revokeForm.scope_id = '' })
watch(() => revokeForm.system, () => { revokeForm.module = '' })

watch(() => grantForm.authentik_sub, (sub) => {
  const user = members.value.find(m => m.authentik_sub === sub)
  if (!user) return
  grantForm.email = user.email || ''
  grantForm.display_name = user.display_name || ''
})

onMounted(loadCatalogs)
</script>
