<template>
  <div>
    <h2 style="margin-bottom: 24px">操作日志</h2>

    <el-card shadow="never">
      <el-tabs v-model="activeSource">
        <el-tab-pane label="租户平台" name="TENANT">
          <div class="toolbar responsive-toolbar">
            <el-select
              v-model="tenantFilters.moduleType"
              placeholder="模块"
              style="width: 180px"
              clearable
              @change="handleTenantModuleChange"
            >
              <el-option label="全部模块" value="" />
              <el-option label="控制台" value="CONSOLE" />
              <el-option label="应用管理" value="APP" />
              <el-option label="子账号管理" value="SUB_ACCOUNT" />
              <el-option label="服务管理" value="SERVICE" />
              <el-option label="密钥验证" value="APP_SECRET" />
              <el-option label="邮箱验证" value="EMAIL_VERIFY" />
            </el-select>
            <el-button :loading="tenantLoading" @click="loadTenantLogs">刷新</el-button>
          </div>

          <div class="table-wrap">
            <el-table :data="tenantLogs" v-loading="tenantLoading" border stripe>
              <el-table-column prop="createdAt" label="时间" width="180">
                <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
              </el-table-column>
              <el-table-column prop="moduleType" label="模块" width="140">
                <template #default="{ row }">
                  <el-tag size="small" effect="plain">{{ tenantModuleLabel(row.moduleType) }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column prop="action" label="动作" width="180" />
              <el-table-column prop="resourceType" label="资源类型" width="140" />
              <el-table-column prop="resourceId" label="资源ID" min-width="220" show-overflow-tooltip />
              <el-table-column prop="operator" label="操作人" width="180" />
              <el-table-column label="详情" min-width="280">
                <template #default="{ row }">
                  <span class="detail">{{ formatDetail(row.detailJson) }}</span>
                </template>
              </el-table-column>
            </el-table>
          </div>

          <el-pagination
            style="margin-top: 16px"
            layout="total, prev, pager, next"
            :total="tenantTotal"
            :page-size="tenantPageSize"
            :current-page="tenantPage + 1"
            @current-change="handleTenantPageChange"
          />
        </el-tab-pane>

        <el-tab-pane label="版本管理" name="UPDATE">
          <div class="toolbar responsive-toolbar">
            <el-select
              v-model="updateAppKey"
              placeholder="选择应用"
              style="width: 320px"
              filterable
              @change="handleUpdateAppChange"
            >
              <el-option
                v-for="app in apps"
                :key="app.appKey"
                :label="`${app.name} · ${app.packageName}`"
                :value="app.appKey"
              />
            </el-select>
            <el-input-number v-model="updateLimit" :min="20" :max="200" :step="10" controls-position="right" />
            <el-button :loading="updateLoading" @click="loadUpdateLogs">刷新</el-button>
          </div>

          <div class="table-wrap">
            <el-table :data="updateLogs" v-loading="updateLoading" border stripe>
              <el-table-column prop="createdAt" label="时间" width="180">
                <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
              </el-table-column>
              <el-table-column prop="resourceType" label="资源类型" width="140">
                <template #default="{ row }">
                  <el-tag size="small" effect="plain">{{ updateResourceLabel(row.resourceType) }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column prop="action" label="动作" width="160">
                <template #default="{ row }">{{ updateActionLabel(row.action) }}</template>
              </el-table-column>
              <el-table-column prop="resourceId" label="资源ID" min-width="220" show-overflow-tooltip />
              <el-table-column prop="operator" label="操作人" width="180" />
              <el-table-column label="原因 / 详情" min-width="320">
                <template #default="{ row }">
                  <span class="detail">{{ row.reason || formatDetail(row.detailJson) }}</span>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue'
import { appApi, type App } from '@/api/app'
import { updateAdminApi, type OperationLog as UpdateOperationLog } from '@/api/update'
import { operationLogApi, type TenantOperationLog } from '@/api/operationLog'

const activeSource = ref<'TENANT' | 'UPDATE'>('TENANT')

const tenantLoading = ref(false)
const tenantLogs = ref<TenantOperationLog[]>([])
const tenantTotal = ref(0)
const tenantPage = ref(0)
const tenantPageSize = ref(20)
const tenantFilters = reactive({
  moduleType: '',
})

const updateLoading = ref(false)
const updateLogs = ref<UpdateOperationLog[]>([])
const updateLimit = ref(100)
const apps = ref<App[]>([])
const updateAppKey = ref('')

onMounted(async () => {
  await Promise.all([
    loadApps(),
    loadTenantLogs(),
  ])
})

watch(activeSource, async (value) => {
  if (value === 'UPDATE' && !apps.value.length) {
    await loadApps()
  }
  if (value === 'UPDATE') {
    await loadUpdateLogs()
  }
})

async function loadApps() {
  if (apps.value.length) return
  try {
    const res = await appApi.list()
    apps.value = res.data.data
    if (!updateAppKey.value && apps.value.length) {
      updateAppKey.value = apps.value[0].appKey
    }
  } catch {
    // ignore; empty state will be shown in the selector
  }
}

async function loadTenantLogs() {
  tenantLoading.value = true
  try {
    const res = await operationLogApi.list({
      moduleType: tenantFilters.moduleType || undefined,
      page: tenantPage.value,
      size: tenantPageSize.value,
    })
    const data = res.data.data
    tenantLogs.value = data.content ?? []
    tenantTotal.value = data.totalElements ?? 0
  } finally {
    tenantLoading.value = false
  }
}

async function loadUpdateLogs() {
  if (!updateAppKey.value) {
    updateLogs.value = []
    return
  }
  updateLoading.value = true
  try {
    const res = await updateAdminApi.listOperationLogs(updateAppKey.value, updateLimit.value)
    updateLogs.value = res.data.data ?? []
  } finally {
    updateLoading.value = false
  }
}

function handleTenantPageChange(nextPage: number) {
  tenantPage.value = nextPage - 1
  loadTenantLogs()
}

function handleTenantModuleChange() {
  tenantPage.value = 0
  loadTenantLogs()
}

function handleUpdateAppChange() {
  loadUpdateLogs()
}

function tenantModuleLabel(moduleType: string) {
  return {
    CONSOLE: '控制台',
    APP: '应用管理',
    SUB_ACCOUNT: '子账号管理',
    SERVICE: '服务管理',
    APP_SECRET: '应用密钥',
    EMAIL_VERIFY: '邮箱验证',
  }[moduleType] ?? moduleType
}

function updateResourceLabel(resourceType: string) {
  return {
    APP_VERSION: '应用版本',
    RN_BUNDLE: 'RN 包',
    STORE_CONFIG: '应用市场',
    PUBLISH_CONFIG: '发布配置',
    GRAY_MEMBER: '灰度成员',
    STORE_SUBMIT: '市场提交流程',
    SERVICE: '服务配置',
  }[resourceType] ?? resourceType
}

function updateActionLabel(action: string) {
  return {
    UPLOAD: '上传',
    PUBLISH: '发布',
    REPUBLISH: '重新发布',
    SCHEDULE_PUBLISH: '定时发布',
    UPDATE_FORCE: '修改强更',
    UNPUBLISH: '下架',
    GRAY_UPDATE: '灰度调整',
    STORE_SUBMIT: '提交市场',
    CREATE_STORE_CONFIG: '创建配置',
    UPDATE_STORE_CONFIG: '更新配置',
    DELETE_STORE_CONFIG: '删除配置',
    AUTO_PUBLISH: '自动发布',
    REQUEST_SERVICE_ACTIVATION: '申请开通',
    UPDATE_SERVICE_CONFIG: '更新服务配置',
    DISABLE_SERVICE: '停用服务',
    VIEW_DASHBOARD: '查看控制台',
  }[action] ?? action
}

function formatDetail(detailJson?: string) {
  if (!detailJson) return '-'
  try {
    const parsed = JSON.parse(detailJson)
    if (parsed === null || parsed === undefined) return '-'
    return typeof parsed === 'string' ? parsed : JSON.stringify(parsed)
  } catch {
    return detailJson
  }
}

function formatTime(value: string | number | null | undefined) {
  if (value === null || value === undefined || value === '') return '-'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return String(value)
  return date.toLocaleString('zh-CN')
}
</script>

<style scoped>
.toolbar {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
  align-items: center;
}

.responsive-toolbar {
  flex-wrap: wrap;
}

.table-wrap {
  overflow-x: auto;
}

.detail {
  display: inline-block;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 767px) {
  .responsive-toolbar {
    align-items: stretch;
  }

  .responsive-toolbar :deep(.el-select),
  .responsive-toolbar :deep(.el-button),
  .responsive-toolbar :deep(.el-input-number) {
    width: 100%;
  }

  .table-wrap :deep(.el-table) {
    min-width: 900px;
  }
}
</style>
