"use server"

import { getTranslations } from "next-intl/server"
import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"
import { handleActionError } from "@/shared/lib/action-utils"

import {
  getDraftLockStatus,
  acquireDraftLock,
  renewDraftLock,
  releaseDraftLock,
  type DraftLockStatus,
  type AcquireLockResult,
} from "./data-access-drafts"
import { assertClassInScope } from "./lib/scope-check"
import { getUserNamesByIds } from "@/modules/users/data-access"

/**
 * P3-6 协同录入锁 Server Actions。
 *
 * 锁的获取/续期/释放都通过 Server Action 完成，
 * 调用方需传入 classId+subjectId+type 三元组定位锁。
 * 所有 Action 强制校验 GRADE_RECORD_MANAGE 权限 + 班级 scope。
 */

/**
 * 解析锁持有者姓名（避免 data-access 跨模块 join）。
 */
async function enrichLockStatusName(
  status: DraftLockStatus
): Promise<DraftLockStatus> {
  if (!status.lockedBy) return status
  const names = await getUserNamesByIds([status.lockedBy])
  const info = names.get(status.lockedBy)
  return { ...status, lockedByName: info?.name ?? null }
}

/**
 * 查询锁状态（进入页面时调用）。
 */
export async function getDraftLockStatusAction(params: {
  classId: string
  subjectId: string
  type: string
}): Promise<ActionState<DraftLockStatus>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)

    const scopeError = assertClassInScope(ctx.dataScope, params.classId)
    if (scopeError) {
      const t = await getTranslations("grades")
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const status = await getDraftLockStatus({
      classId: params.classId,
      subjectId: params.subjectId,
      type: params.type,
      currentUserId: ctx.userId,
    })

    return { success: true, data: await enrichLockStatusName(status) }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 获取编辑锁（进入编辑页或被抢占后重试时调用）。
 */
export async function acquireDraftLockAction(params: {
  classId: string
  subjectId: string
  type: string
}): Promise<ActionState<AcquireLockResult>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_MANAGE)

    const scopeError = assertClassInScope(ctx.dataScope, params.classId)
    if (scopeError) {
      const t = await getTranslations("grades")
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const result = await acquireDraftLock({
      classId: params.classId,
      subjectId: params.subjectId,
      type: params.type,
      userId: ctx.userId,
    })

    if (!result.acquired) {
      // 锁被他人持有，返回结构化信息让前端展示冲突提示
      const enriched = await enrichLockStatusName(result.status)
      return {
        success: false,
        data: { acquired: false, lockToken: null, status: enriched },
      }
    }

    return {
      success: true,
      data: {
        acquired: true,
        lockToken: result.lockToken,
        status: result.status,
      },
    }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 续期锁（心跳）。
 *
 * 前端每 2-3 分钟调用一次，避免长时间编辑时锁过期。
 * 返回新的 lockToken，前端需替换本地保存的旧 token。
 */
export async function renewDraftLockAction(params: {
  classId: string
  subjectId: string
  type: string
  lockToken: string
}): Promise<ActionState<AcquireLockResult>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_MANAGE)

    const scopeError = assertClassInScope(ctx.dataScope, params.classId)
    if (scopeError) {
      const t = await getTranslations("grades")
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const result = await renewDraftLock({
      classId: params.classId,
      subjectId: params.subjectId,
      type: params.type,
      userId: ctx.userId,
      lockToken: params.lockToken,
    })

    if (!result.acquired) {
      const enriched = await enrichLockStatusName(result.status)
      return {
        success: false,
        data: { acquired: false, lockToken: null, status: enriched },
      }
    }

    return {
      success: true,
      data: {
        acquired: true,
        lockToken: result.lockToken,
        status: result.status,
      },
    }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 释放锁（提交成功或用户主动退出时调用）。
 *
 * 失败不阻断主流程（如批量录入成功后释放锁失败仅记日志）。
 */
export async function releaseDraftLockAction(params: {
  classId: string
  subjectId: string
  type: string
  lockToken: string
}): Promise<ActionState<{ released: true }>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_MANAGE)

    const scopeError = assertClassInScope(ctx.dataScope, params.classId)
    if (scopeError) {
      const t = await getTranslations("grades")
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const released = await releaseDraftLock({
      classId: params.classId,
      subjectId: params.subjectId,
      type: params.type,
      userId: ctx.userId,
      lockToken: params.lockToken,
    })

    if (!released) {
      // 锁可能已被抢占或自动过期，返回成功以避免阻断主流程
      // 前端只需知道"无需再持有该锁"
    }

    return { success: true, data: { released: true } }
  } catch (e) {
    // 释放失败不应阻断主流程，降级为日志
    console.error("[grades] releaseDraftLockAction failed:", e)
    return { success: true, data: { released: true } }
  }
}
