<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { getDatasetList, type DatasetItem } from '@/api/modules/dataset'
import { getTrainedModels } from '@/api/modules/model'
import type { TrainedModel } from '@/types'
import { getUsers, type SystemUser } from '@/api/modules/system'
import { getResourceAcl, setResourceAcl, type AclEntry } from '@/api/modules/resource-acl'

const loading = ref(false)
const saving = ref(false)

// 资源类型选项
const resourceTypes = [
  { value: 'dataset', label: '数据集' },
  { value: 'trained_model', label: '训练产物（微调模型）' },
]

// 资源列表
const datasets = ref<DatasetItem[]>([])
const models = ref<TrainedModel[]>([])
const users = ref<SystemUser[]>([])

// 当前选择
const form = reactive({
  resourceType: 'dataset',
  resourceIds: [] as string[],
  resourceNames: '' as string,
})

// ACL 编辑
const aclEntries = ref<AclEntry[]>([])
const showAddEntry = ref(false)
const newEntry = reactive({
  principal_id: '',
  permissions: ['read', 'execute'] as string[],
})

const permissionOptions = [
  { label: '查看 (read)', value: 'read' },
  { label: '编辑 (write)', value: 'write' },
  { label: '使用 (execute)', value: 'execute' },
  { label: '下载 (download)', value: 'download' },
  { label: '删除 (delete)', value: 'delete' },
  { label: '全部权限 (admin)', value: 'admin' },
]

// 加载所有数据
async function loadAll() {
  loading.value = true
  try {
    const [dsRes, trainedRes, userRes] = await Promise.all([
      getDatasetList().catch(() => []),
      getTrainedModels().catch(() => ({ models: [] })),
      getUsers().catch(() => []),
    ])
    datasets.value = dsRes || []
    models.value = trainedRes?.models || []
    users.value = userRes || []
  } finally {
    loading.value = false
  }
}

// 获取当前资源类型的列表
function currentResourceList() {
  if (form.resourceType === 'dataset') {
    return datasets.value.map((d) => ({ id: d.id, name: d.name || d.id }))
  }
  if (form.resourceType === 'trained_model') {
    return models.value.map((m) => ({ id: String(m.id || m.name || ''), name: m.name || String(m.id) || '' }))
  }
  return []
}

// 获取当前资源的名称
function getResourceName(id: string) {
  return currentResourceList().find((r) => r.id === id)?.name || id
}

// 选择资源后加载 ACL
async function onResourceChange() {
  if (!form.resourceIds || form.resourceIds.length === 0) {
    aclEntries.value = []
    form.resourceNames = ''
    return
  }
  // 显示选中的资源名称
  const names = form.resourceIds.map((id) => getResourceName(id))
  form.resourceNames = names.join('、')
  
  // 加载第一个资源的 ACL 作为初始值（多个资源的 ACL 合并显示）
  try {
    const res = await getResourceAcl(form.resourceType, form.resourceIds[0])
    if (Array.isArray(res)) {
      aclEntries.value = res.map((e: any) => ({
        ...e,
        principal_type: e.principal_type || 'user',
        permissions: Array.isArray(e.permissions) ? e.permissions : [],
      }))
    } else if (res && Array.isArray((res as any).entries)) {
      aclEntries.value = (res as any).entries.map((e: any) => ({
        ...e,
        principal_type: e.principal_type || 'user',
        permissions: Array.isArray(e.permissions) ? e.permissions : [],
      }))
    } else {
      aclEntries.value = []
    }
  } catch (e) {
    console.error('加载 ACL 失败:', e)
    aclEntries.value = []
  }
}

// 切换资源类型时重置
function onTypeChange() {
  form.resourceIds = []
  form.resourceNames = ''
  aclEntries.value = []
}

// 添加授权条目
function addEntry() {
  const trimmedId = (newEntry.principal_id || '').trim()
  if (!trimmedId) {
    ElMessage.warning('请选择要授权的用户')
    return
  }
  if (!newEntry.permissions || newEntry.permissions.length === 0) {
    ElMessage.warning('请至少选择一个权限')
    return
  }
  const exists = aclEntries.value.some((e) => e.principal_id === trimmedId)
  if (exists) {
    ElMessage.warning('该用户已存在，请先删除再重新添加')
    return
  }
  aclEntries.value.push({
    principal_type: 'user',
    principal_id: trimmedId,
    permissions: [...newEntry.permissions],
  })
  showAddEntry.value = false
  newEntry.principal_id = ''
  newEntry.permissions = ['read', 'execute']
}

// 删除授权条目
function removeEntry(index: number) {
  aclEntries.value.splice(index, 1)
}

// 保存 ACL
async function saveAcl() {
  if (!form.resourceIds || form.resourceIds.length === 0) {
    ElMessage.warning('请先选择资源')
    return
  }
  if (aclEntries.value.length === 0) {
    ElMessage.warning('请至少添加一个授权用户')
    return
  }
  saving.value = true
  try {
    // 为每个选中的资源保存相同的 ACL 授权
    for (const resourceId of form.resourceIds) {
      await setResourceAcl(form.resourceType, resourceId, aclEntries.value)
    }
    ElMessage.success(`已为 ${form.resourceIds.length} 个资源保存授权配置`)
  } catch (e: any) {
    ElMessage.error(e?.message || '保存失败')
  } finally {
    saving.value = false
  }
}

// 显示名称
function principalName(entry: AclEntry) {
  const user = users.value.find((u) => u.id === entry.principal_id)
  return user ? `${user.display_name || user.username}` : entry.principal_id
}

onMounted(loadAll)
</script>

<template>
  <div class="page" v-loading="loading">
    <h2 class="page-title">资源授权管理</h2>
    <p class="page-desc">将数据集或微调模型授权给指定用户使用。被授权的用户可以在自己的页面看到并使用该资源。</p>

    <!-- 步骤1：选择资源 -->
    <el-card class="section-card">
      <template #header>
        <span>① 选择要授权的资源</span>
      </template>
      <el-form :inline="true" label-width="90px">
        <el-form-item label="资源类型">
          <el-select v-model="form.resourceType" @change="onTypeChange" style="width: 200px">
            <el-option v-for="t in resourceTypes" :key="t.value" :label="t.label" :value="t.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="选择资源">
          <el-select
            v-model="form.resourceIds"
            multiple
            filterable
            collapse-tags
            collapse-tags-tooltip
            placeholder="搜索并选择多个资源..."
            style="width: 400px"
            @change="onResourceChange"
          >
            <el-option
              v-for="r in currentResourceList()"
              :key="r.id"
              :label="`${r.name} (${r.id.slice(0, 8)}...)`"
              :value="r.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 步骤2：当前授权列表 + 添加授权 -->
    <el-card class="section-card" v-if="form.resourceIds.length > 0">
      <template #header>
        <div style="display: flex; justify-content: space-between; align-items: center">
          <span>② 管理授权 — {{ form.resourceNames }}</span>
          <el-button type="primary" size="small" @click="showAddEntry = true">+ 添加授权</el-button>
        </div>
      </template>

      <!-- 已有授权列表 -->
      <el-table :data="aclEntries" border empty-text="暂无授权，点击上方按钮添加" style="width: 100%">
        <el-table-column label="用户">
          <template #default="{ row }">{{ principalName(row) }}</template>
        </el-table-column>
        <el-table-column label="授权资源" min-width="200">
          <template #default>
            <el-tag v-for="(id, idx) in form.resourceIds" :key="id" size="small" style="margin: 2px">
              {{ getResourceName(id) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="权限">
          <template #default="{ row }">
            <el-space wrap>
              <el-tag
                v-for="p in row.permissions"
                :key="p"
                size="small"
                :type="p === 'admin' ? 'danger' : p === 'delete' || p === 'write' ? 'warning' : ''"
              >{{ p }}</el-tag>
            </el-space>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" align="center">
          <template #default="{ $index }">
            <el-button type="danger" size="small" link @click="removeEntry($index)">移除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 添加授权表单 -->
      <el-divider v-if="showAddEntry" content-position="left">添加新授权</el-divider>
      <div v-if="showAddEntry" class="add-entry-form">
        <el-form :inline="true" label-width="80px">
          <el-form-item label="选择用户">
            <el-select
              v-model="newEntry.principal_id"
              filterable
              placeholder="选择要授权的用户"
              style="width: 240px"
            >
              <el-option
                v-for="u in users"
                :key="u.id"
                :label="`${u.display_name || u.username} (${u.username})`"
                :value="u.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="权限">
            <el-checkbox-group v-model="newEntry.permissions">
              <el-checkbox v-for="p in permissionOptions" :key="p.value" :value="p.value">{{ p.label }}</el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="addEntry">确认添加</el-button>
            <el-button @click="showAddEntry = false">取消</el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 保存按钮 -->
      <div class="save-bar">
        <el-button type="primary" :loading="saving" @click="saveAcl">保存授权配置</el-button>
      </div>
    </el-card>

    <!-- 使用说明 -->
    <el-card class="section-card help-card">
      <template #header><span>使用说明</span></template>
      <div class="help-content">
        <p><strong>什么是资源授权？</strong></p>
        <p>默认情况下，普通用户只能看到自己创建的资源。通过授权，管理员可以让指定用户也能看到和使用别人的资源。</p>
        <br />
        <p><strong>典型场景：</strong></p>
        <ul>
          <li>zhangsan 训练出了模型 ft_qwen_001，admin 授权给 lisi，lisi 可以用这个模型做推理</li>
          <li>admin 上传了公共数据集，授权给指定用户，被授权用户可以在训练时使用该数据集</li>
        </ul>
        <br />
        <p><strong>权限说明：</strong></p>
        <ul>
          <li><code>read</code> - 在列表中看到该资源</li>
          <li><code>execute</code> - 用该资源做训练/推理/评测</li>
          <li><code>write</code> - 修改资源信息</li>
          <li><code>download</code> - 下载文件</li>
          <li><code>delete</code> - 删除资源</li>
          <li><code>admin</code> - 全部权限（含转授权）</li>
        </ul>
      </div>
    </el-card>
  </div>
</template>

<style scoped lang="scss">
.page {
  padding: 20px;
  max-width: 1100px;
}
.page-title {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 8px;
}
.page-desc {
  color: #666;
  margin: 0 0 24px;
  font-size: 14px;
}
.section-card {
  margin-bottom: 20px;
}
.add-entry-form {
  background: #f9fafc;
  padding: 16px;
  border-radius: 8px;
  border: 1px dashed #dcdfe6;
}
.save-bar {
  text-align: right;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #ebeef5;
}
.help-card {
  .help-content {
    font-size: 14px;
    line-height: 1.8;
    color: #555;
    ul {
      padding-left: 20px;
      margin: 4px 0;
      li { margin-bottom: 4px; }
    }
    code {
      background: #f0f0f0;
      padding: 2px 6px;
      border-radius: 4px;
      font-size: 13px;
    }
  }
}
</style>
