"use server"

import { revalidatePath } from "next/cache"

import type { ActionState } from "@/shared/types/action-state"
import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { trackEvent } from "@/shared/lib/track-event"

import {
  generateInvitationCodes as generateInvitationCodesDa,
  listInvitationCodes as listInvitationCodesDa,
  deleteInvitationCode as deleteInvitationCodeDa,
  validateInvitationCode as validateInvitationCodeDa,
} from "./data-access"
import { GenerateInvitationCodesSchema } from "./schema"
import type {
  GenerateInvitationCodesResult,
  InvitationCodeRecord,
} from "./types"

/**
 * 批量生成邀请码（audit-P2-3 新增）
 *
 * 权限：USER_MANAGE（管理员）
 * 输入：{ count, role, email?, classId?, expiresAt?, notes? }
 * 返回：含明文 code 的完整记录列表（仅此一次返回明文）
 */
export async function generateInvitationCodesAction(
  input: unknown,
): Promise<ActionState<GenerateInvitationCodesResult>> {
  try {
    const ctx = await requirePermission(Permissions.USER_MANAGE)

    const parsed = GenerateInvitationCodesSchema.safeParse(input)
    if (!parsed.success) {
      return {
        success: false,
        message: parsed.error.issues[0]?.message ?? "Invalid input",
      }
    }

    const data = parsed.data
    const result = await generateInvitationCodesDa(
      {
        count: data.count,
        role: data.role,
        email: data.email?.trim() || null,
        classId: data.classId?.trim() || null,
        expiresAt: data.expiresAt ? new Date(data.expiresAt) : null,
        notes: data.notes?.trim() || null,
      },
      ctx.userId,
    )

    void trackEvent({
      event: "invitation_codes.generated",
      userId: ctx.userId,
      properties: {
        count: result.codes.length,
        role: data.role,
        batchId: result.batchId,
      },
    })

    revalidatePath("/admin/invitation-codes")

    return { success: true, data: result }
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Failed to generate invitation codes"
    return { success: false, message }
  }
}

/**
 * 列出邀请码（audit-P2-3 新增）
 *
 * 权限：USER_MANAGE（管理员）
 * 返回：邀请码记录列表（已使用 + 未使用，按创建时间倒序）
 */
export async function listInvitationCodesAction(): Promise<
  ActionState<InvitationCodeRecord[]>
> {
  try {
    await requirePermission(Permissions.USER_MANAGE)

    const records = await listInvitationCodesDa(200, true)
    return { success: true, data: records }
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Failed to list invitation codes"
    return { success: false, message }
  }
}

/**
 * 删除邀请码（audit-P2-3 新增）
 *
 * 权限：USER_MANAGE（管理员）
 * 仅允许删除未被使用的邀请码（已使用的保留作为审计记录）。
 */
export async function deleteInvitationCodeAction(
  codeId: string,
): Promise<ActionState<null>> {
  try {
    const ctx = await requirePermission(Permissions.USER_MANAGE)

    const deleted = await deleteInvitationCodeDa(codeId)
    if (!deleted) {
      return {
        success: false,
        message:
          "Invitation code not found or already used (used codes cannot be deleted)",
      }
    }

    void trackEvent({
      event: "invitation_codes.deleted",
      userId: ctx.userId,
      targetId: codeId,
    })

    revalidatePath("/admin/invitation-codes")
    return { success: true, data: null }
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Failed to delete invitation code"
    return { success: false, message }
  }
}

/**
 * 校验邀请码（公开接口，供注册流程预检，audit-P2-3 新增）
 *
 * 不需要权限校验：注册流程需要预检邀请码可用性。
 * 不返回邀请码明文（脱敏）。
 */
export async function validateInvitationCodeAction(
  code: string,
  email: string,
): Promise<ActionState<{ valid: boolean; reason?: string; role?: string }>> {
  try {
    const result = await validateInvitationCodeDa(code, email)
    return {
      success: true,
      data: {
        valid: result.valid,
        reason: result.reason,
        role: result.code?.role,
      },
    }
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Failed to validate invitation code"
    return { success: false, message }
  }
}
