"use server"

import { revalidatePath } from "next/cache"
import { PermissionDeniedError, requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"
import { trackEvent } from "@/shared/lib/track-event"
import { getSession } from "@/shared/lib/session"

import {
  getDataChangeLogs,
  getDataChangeLogsForExport,
  getDataChangeStats,
  getDataChangeTableOptions,
  getAuditLogsForExport,
  getLoginLogsForExport,
} from "./data-access"
import {
  buildAuditLogExport,
  buildDataChangeLogExport,
  buildLoginLogExport,
} from "./export"
import {
  getAuditRetentionConfig,
  saveAuditRetentionConfig,
  purgeExpiredAuditLogs,
} from "./retention"
import type {
  AuditLogQueryParams,
  AuditRetentionConfig,
  DataChangeLog,
  DataChangeLogQueryParams,
  DataChangeStat,
  LoginLogQueryParams,
  PurgeResult,
} from "./types"

export async function getDataChangeLogsAction(
  params?: DataChangeLogQueryParams
): Promise<
  ActionState<{
    items: DataChangeLog[]
    total: number
    page: number
    pageSize: number
    totalPages: number
    tableOptions: string[]
    stats: DataChangeStat[]
  }>
> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const [result, tableOptions, stats] = await Promise.all([
      getDataChangeLogs(params),
      getDataChangeTableOptions(),
      getDataChangeStats(),
    ])
    return {
      success: true,
      data: {
        items: result.items,
        total: result.total,
        page: result.page,
        pageSize: result.pageSize,
        totalPages: result.totalPages,
        tableOptions,
        stats,
      },
    }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

export async function exportAuditLogsAction(
  params?: AuditLogQueryParams
): Promise<ActionState<{ buffer: Buffer; filename: string }>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const items = await getAuditLogsForExport(params)
    const { buffer, filename } = await buildAuditLogExport(items)

    const session = await getSession()
    await trackEvent({
      event: "audit.exported",
      userId: session?.user?.id,
      targetType: "audit_log",
      properties: { type: "audit", count: items.length },
    })

    return { success: true, data: { buffer, filename } }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

export async function exportLoginLogsAction(
  params?: LoginLogQueryParams
): Promise<ActionState<{ buffer: Buffer; filename: string }>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const items = await getLoginLogsForExport(params)
    const { buffer, filename } = await buildLoginLogExport(items)

    const session = await getSession()
    await trackEvent({
      event: "audit.exported",
      userId: session?.user?.id,
      targetType: "login_log",
      properties: { type: "login", count: items.length },
    })

    return { success: true, data: { buffer, filename } }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

export async function exportDataChangeLogsAction(
  params?: DataChangeLogQueryParams
): Promise<ActionState<{ buffer: Buffer; filename: string }>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const items = await getDataChangeLogsForExport(params)
    const { buffer, filename } = await buildDataChangeLogExport(items)

    const session = await getSession()
    await trackEvent({
      event: "audit.exported",
      userId: session?.user?.id,
      targetType: "data_change_log",
      properties: { type: "dataChange", count: items.length },
    })

    return { success: true, data: { buffer, filename } }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

// ─── 保留策略管理 ──────────────────────────────────────────

export async function getAuditRetentionConfigAction(): Promise<ActionState<AuditRetentionConfig>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const config = await getAuditRetentionConfig()
    return { success: true, data: config }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

export async function saveAuditRetentionConfigAction(
  config: AuditRetentionConfig,
): Promise<ActionState<AuditRetentionConfig>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const session = await getSession()
    await saveAuditRetentionConfig(config, session?.user?.id)

    void trackEvent({
      event: "audit.retention",
      userId: session?.user?.id,
      targetType: "audit_retention",
      properties: {
        action: "save_config",
        retentionDays: config.retentionDays,
        loginLogRetentionDays: config.loginLogRetentionDays,
        autoCleanupEnabled: config.autoCleanupEnabled,
      },
    })

    revalidatePath("/admin/audit-logs/overview")
    return { success: true, data: config }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

export async function purgeAuditLogsAction(
  retentionDays?: number,
  loginLogRetentionDays?: number,
): Promise<ActionState<PurgeResult>> {
  try {
    await requirePermission(Permissions.AUDIT_LOG_READ)
    const session = await getSession()

    // audit-P2-5: 未显式传入时读取配置（含 loginLogRetentionDays）
    const config = retentionDays === undefined ? await getAuditRetentionConfig() : null
    const days = retentionDays ?? config?.retentionDays ?? 180
    const loginDays = loginLogRetentionDays ?? config?.loginLogRetentionDays
    const result = await purgeExpiredAuditLogs(days, loginDays)

    void trackEvent({
      event: "audit.retention",
      userId: session?.user?.id,
      targetType: "audit_retention",
      properties: {
        action: "purge",
        retentionDays: days,
        loginLogRetentionDays: loginDays,
        ...result,
      },
    })

    revalidatePath("/admin/audit-logs/overview")
    revalidatePath("/admin/audit-logs")
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) return { success: false, message: e.message }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}
