<template>
  <div class="page-content">
    <div class="mb-5 flex items-center justify-between gap-4">
      <div>
        <h2 class="text-xl font-semibold">渠道管理</h2>
        <p class="text-g-500 mt-1 text-sm">企业微信/钉钉/飞书/通用 Webhook 渠道:入站消息经绑定模型应答后按平台协议回复</p>
      </div>
      <ElButton type="primary" @click="openCreate">新增渠道</ElButton>
    </div>

    <ElAlert class="mb-4" type="info" :closable="false" title="接入方式:平台回调/机器人 Webhook 指向 POST /v1/channels/{code}/inbound;企微需在管理端配置回调 URL 并启用签名校验。" />

    <ElTable v-loading="loading" :data="channels" row-key="id">
      <ElTableColumn prop="code" label="代码" width="140" />
      <ElTableColumn prop="name" label="名称" min-width="140" />
      <ElTableColumn label="类型" width="110">
        <template #default="{ row }">{{ kindLabel(row.kind) }}</template>
      </ElTableColumn>
      <ElTableColumn label="绑定模型" min-width="180">
        <template #default="{ row }">{{ modelLabel(row.model_binding) }}</template>
      </ElTableColumn>
      <ElTableColumn label="API Key" width="90">
        <template #default="{ row }">
          <ElTag :type="row.has_api_key ? 'success' : 'info'">{{ row.has_api_key ? '已配置' : '未配置' }}</ElTag>
        </template>
      </ElTableColumn>
      <ElTableColumn label="部门范围" min-width="150">
        <template #default="{ row }">
          <ElTag v-if="!row.department_ids || !row.department_ids.length" type="info">全局</ElTag>
          <ElTag v-else type="primary">{{ row.department_ids.length }} 个部门</ElTag>
        </template>
      </ElTableColumn>
      <ElTableColumn label="状态" width="90">
        <template #default="{ row }">
          <ElTag :type="row.enabled ? 'success' : 'info'">{{ row.enabled ? '启用' : '停用' }}</ElTag>
        </template>
      </ElTableColumn>
      <ElTableColumn label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <ElButton link type="success" :loading="testingId === row.id" @click="test(row)">测试</ElButton>
          <ElButton link type="primary" @click="openGrants(row)">授权</ElButton>
          <ElButton link type="primary" @click="openEdit(row)">编辑</ElButton>
          <ElButton link type="danger" @click="remove(row)">删除</ElButton>
        </template>
      </ElTableColumn>
    </ElTable>

    <ElDialog v-model="dialogVisible" :title="editingId ? '编辑渠道' : '新增渠道'" width="640px">
      <ElForm :model="form" label-width="110px">
        <ElFormItem label="代码" required>
          <ElInput v-model="form.code" :disabled="!!editingId" placeholder="小写字母开头,如 wecom-main" />
        </ElFormItem>
        <ElFormItem label="名称" required><ElInput v-model="form.name" /></ElFormItem>
        <ElFormItem label="类型" required>
          <ElSelect v-model="form.kind" class="w-full">
            <ElOption label="通用 Webhook" value="webhook" />
            <ElOption label="企业微信" value="wecom" />
            <ElOption label="钉钉" value="dingtalk" />
            <ElOption label="飞书" value="feishu" />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="绑定模型">
          <div class="flex w-full gap-2">
            <ElInput v-model="form.binding_provider" placeholder="供应商代码(留空用默认)" />
            <ElInput v-model="form.binding_model" placeholder="模型名,如 gpt-4o-mini" />
          </div>
        </ElFormItem>
        <ElFormItem label="部门范围">
          <ElSelect v-model="form.department_ids" multiple filterable class="w-full" placeholder="留空 = 全局渠道(所有部门可见)">
            <ElOption v-for="department in departments" :key="department.id" :label="department.name" :value="department.id" />
          </ElSelect>
          <div class="text-g-400 text-xs">仅列出的部门可见此渠道;用户级授权在「授权」中单独管理</div>
        </ElFormItem>
        <ElFormItem label="网关 API Key">
          <ElInput v-model="form.api_key" type="password" show-password :placeholder="editingId ? '留空不更换' : '必填'" />
        </ElFormItem>
        <ElFormItem label="入站令牌">
          <ElInput v-model="form.inbound_token" type="password" show-password placeholder="webhook/企微回调鉴权令牌" />
        </ElFormItem>
        <ElFormItem label="启用">
          <ElSwitch v-model="form.enabled" />
        </ElFormItem>
        <template v-if="form.kind === 'wecom'">
          <ElFormItem label="CorpID"><ElInput v-model="form.corp_id" /></ElFormItem>
          <ElFormItem label="Secret"><ElInput v-model="form.secret" type="password" show-password /></ElFormItem>
          <ElFormItem label="AgentID"><ElInput v-model="form.agent_id" /></ElFormItem>
        </template>
        <template v-else-if="form.kind === 'dingtalk'">
          <ElFormItem label="机器人 Token"><ElInput v-model="form.ding_robot_token" /></ElFormItem>
        </template>
        <template v-else-if="form.kind === 'feishu'">
          <ElFormItem label="App ID"><ElInput v-model="form.feishu_app_id" /></ElFormItem>
          <ElFormItem label="App Secret"><ElInput v-model="form.feishu_app_secret" type="password" show-password /></ElFormItem>
        </template>
      </ElForm>
      <template #footer>
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton type="primary" :loading="saving" @click="submit">保存</ElButton>
      </template>
    </ElDialog>

    <ElDialog v-model="grantsVisible" :title="`渠道授权 · ${grantsChannel?.name || ''}`" width="640px">
      <div class="mb-3 flex gap-2">
        <ElSelect v-model="grantUserID" filterable class="flex-1" placeholder="选择门户用户">
          <ElOption v-for="user in portalUsers" :key="user.id" :label="`${user.display_name || user.login} (${user.login})`" :value="user.id" />
        </ElSelect>
        <ElButton type="primary" :loading="granting" :disabled="!grantUserID" @click="grant">授予</ElButton>
      </div>
      <ElTable :data="grants" row-key="portal_user_id" max-height="360">
        <ElTableColumn prop="user_login" label="用户" min-width="160" />
        <ElTableColumn label="来源" width="100">
          <template #default="{ row }"><ElTag size="small" :type="row.source === 'approval' ? 'warning' : 'primary'">{{ row.source === 'approval' ? '审批' : '手动' }}</ElTag></template>
        </ElTableColumn>
        <ElTableColumn prop="created_at" label="授权时间" width="180" />
        <ElTableColumn label="操作" width="90" fixed="right">
          <template #default="{ row }"><ElButton link type="danger" @click="revoke(row)">撤销</ElButton></template>
        </ElTableColumn>
      </ElTable>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
  import { ElMessage, ElMessageBox } from 'element-plus'
  import request from '@/utils/http'

  interface Channel {
    id: string
    code: string
    name: string
    kind: string
    model_binding: Record<string, any>
    department_ids: string[]
    has_api_key: boolean
    enabled: boolean
  }
  interface ChannelGrant { channel_id: string; channel_code: string; channel_name: string; portal_user_id: string; user_login: string; source: string; created_at: string }
  interface Department { id: string; name: string }
  interface PortalUser { id: string; login: string; display_name: string }

  const kindMap: Record<string, string> = { webhook: 'Webhook', wecom: '企业微信', dingtalk: '钉钉', feishu: '飞书' }
  const kindLabel = (kind: string) => kindMap[kind] || kind
  const modelLabel = (binding: Record<string, any>) => (binding?.model ? `${binding.provider ? binding.provider + ' / ' : ''}${binding.model}` : '未绑定')

  const channels = ref<Channel[]>([])
  const loading = ref(false)
  const saving = ref(false)
  const testingId = ref('')
  const dialogVisible = ref(false)
  const editingId = ref('')
  const departments = ref<Department[]>([])
  const portalUsers = ref<PortalUser[]>([])
  const grantsVisible = ref(false)
  const grantsChannel = ref<Channel>()
  const grants = ref<ChannelGrant[]>([])
  const grantUserID = ref('')
  const granting = ref(false)
  const form = reactive({
    code: '', name: '', kind: 'webhook', binding_provider: '', binding_model: '', api_key: '',
    inbound_token: '', corp_id: '', secret: '', agent_id: '', ding_robot_token: '', feishu_app_id: '', feishu_app_secret: '',
    department_ids: [] as string[],
    enabled: true
  })

  async function load() {
    loading.value = true
    try {
      const [channelList, departmentList, userList] = await Promise.all([
        request.get<Channel[]>({ url: '/api/v1/admin/channels' }),
        request.get<Department[]>({ url: '/api/v1/admin/departments' }),
        request.get<PortalUser[]>({ url: '/api/v1/admin/identities/portal-users' })
      ])
      channels.value = channelList
      departments.value = departmentList
      portalUsers.value = userList
    } finally {
      loading.value = false
    }
  }

  function openCreate() {
    editingId.value = ''
    Object.assign(form, { code: '', name: '', kind: 'webhook', binding_provider: '', binding_model: '', api_key: '', inbound_token: '', corp_id: '', secret: '', agent_id: '', ding_robot_token: '', feishu_app_id: '', feishu_app_secret: '', department_ids: [], enabled: true })
    dialogVisible.value = true
  }

  function openEdit(row: Channel) {
    editingId.value = row.id
    Object.assign(form, {
      code: row.code, name: row.name, kind: row.kind, api_key: '',
      // 显式清空全部平台配置字段:否则上一条渠道的 Secret/Token 会残留并
      // 在保存时静默覆盖当前渠道的凭据。
      inbound_token: '', corp_id: '', secret: '', agent_id: '', ding_robot_token: '', feishu_app_id: '', feishu_app_secret: '',
      binding_provider: row.model_binding?.provider || '', binding_model: row.model_binding?.model || '',
      department_ids: [...(row.department_ids || [])],
      enabled: row.enabled
    })
    dialogVisible.value = true
  }

  async function submit() {
    if (!form.code || !form.name) {
      ElMessage.warning('请填写代码和名称')
      return
    }
    saving.value = true
    try {
      const config: Record<string, string> = {}
      if (form.inbound_token) config.inbound_token = form.inbound_token
      if (form.kind === 'wecom') {
        if (form.corp_id) config.corp_id = form.corp_id
        if (form.secret) config.secret = form.secret
        if (form.agent_id) config.agent_id = form.agent_id
      }
      if (form.kind === 'dingtalk' && form.ding_robot_token) config.ding_robot_token = form.ding_robot_token
      if (form.kind === 'feishu') {
        if (form.feishu_app_id) config.feishu_app_id = form.feishu_app_id
        if (form.feishu_app_secret) config.feishu_app_secret = form.feishu_app_secret
      }
      const payload = {
        code: form.code, name: form.name, kind: form.kind, config,
        model_binding: { provider: form.binding_provider || undefined, model: form.binding_model || undefined },
        department_ids: form.department_ids,
        api_key: form.api_key,
        enabled: form.enabled
      }
      if (editingId.value) {
        await request.put({ url: `/api/v1/admin/channels/${editingId.value}`, params: payload })
        ElMessage.success('渠道已更新')
      } else {
        await request.post({ url: '/api/v1/admin/channels', params: payload })
        ElMessage.success('渠道已创建')
      }
      dialogVisible.value = false
      await load()
    } finally {
      saving.value = false
    }
  }

  async function test(row: Channel) {
    testingId.value = row.id
    try {
      const result = await request.post<{ answer: string }>({ url: `/api/v1/admin/channels/${row.id}/test` })
      ElMessage.success(`模型应答: ${result.answer.slice(0, 60)}`)
    } catch { /* 全局错误提示 */ } finally {
      testingId.value = ''
    }
  }

  async function openGrants(row: Channel) {
    grantsChannel.value = row
    grantUserID.value = ''
    grants.value = await request.get<ChannelGrant[]>({ url: `/api/v1/admin/channels/${row.id}/grants` })
    grantsVisible.value = true
  }

  async function grant() {
    if (!grantUserID.value || !grantsChannel.value) return
    granting.value = true
    try {
      await request.post({ url: `/api/v1/admin/channels/${grantsChannel.value.id}/grants`, params: { portal_user_id: grantUserID.value } })
      ElMessage.success('已授予')
      grantUserID.value = ''
      grants.value = await request.get<ChannelGrant[]>({ url: `/api/v1/admin/channels/${grantsChannel.value.id}/grants` })
    } finally {
      granting.value = false
    }
  }

  async function revoke(row: ChannelGrant) {
    try {
      await ElMessageBox.confirm(`撤销「${row.user_login}」的渠道使用权限？`, '撤销授权', { type: 'warning' })
    } catch {
      return
    }
    if (!grantsChannel.value) return
    await request.del({ url: `/api/v1/admin/channels/${grantsChannel.value.id}/grants/${row.portal_user_id}` })
    grants.value = grants.value.filter((item) => item.portal_user_id !== row.portal_user_id)
    ElMessage.success('已撤销')
  }

  async function remove(row: Channel) {
    try {
      await ElMessageBox.confirm(`确认删除渠道「${row.name}」？`, '删除渠道', { type: 'warning' })
    } catch {
      return
    }
    try {
      await request.del({ url: `/api/v1/admin/channels/${row.id}` })
      ElMessage.success('已删除')
      await load()
    } catch { /* 全局错误提示 */ }
  }

  onMounted(load)
</script>
