import { z } from "zod"

import { MAX_FILE_SIZE } from "@/shared/lib/file-storage"

import type { FileTargetType } from "./types"

/**
 * files 模块 Zod 校验 schema
 *
 * 用于 Server Action 与 API 路由的输入校验，替代手写 typeof 检查与 as 断言。
 */

// FileTargetType 枚举值同步到 Zod（保持单一来源：types.ts）
const FILE_TARGET_TYPES: readonly FileTargetType[] = [
  "exam",
  "textbook",
  "question",
  "announcement",
  "homework",
  "user_avatar",
  "message",
]

export const FileTargetTypeSchema = z.enum(
  FILE_TARGET_TYPES as unknown as [FileTargetType, ...FileTargetType[]]
)

/**
 * 文件上传元数据校验（targetType / targetId 来自 FormData）
 *
 * targetType 可选；targetId 仅在 targetType 提供时才校验长度。
 */
export const UploadMetadataSchema = z.object({
  targetType: FileTargetTypeSchema.optional().nullable(),
  targetId: z
    .string()
    .trim()
    .max(128)
    .optional()
    .nullable()
    .transform((v) => (v && v.length > 0 ? v : null)),
})

export type UploadMetadata = z.infer<typeof UploadMetadataSchema>

/**
 * 批量删除请求体校验
 *
 * - ids 必须为非空字符串数组
 * - 单次最多 100 条，防止超长 SQL
 * - 每条 id 长度上限 128（与 schema.id varchar(128) 一致）
 */
export const BatchDeleteSchema = z.object({
  ids: z
    .array(z.string().min(1).max(128))
    .min(1, "No file ids provided")
    .max(100, "Cannot delete more than 100 files at once"),
})

export type BatchDeleteInput = z.infer<typeof BatchDeleteSchema>

/**
 * 管理员文件列表筛选参数校验
 *
 * - mimeType：精确或前缀匹配（"image/"）
 * - search：文件名模糊匹配
 * - limit：1..200，默认 100
 * - offset：>=0，默认 0
 */
export const FileListQuerySchema = z.object({
  mimeType: z.string().trim().max(128).optional().nullable(),
  search: z.string().trim().max(255).optional().nullable(),
  limit: z.number().int().min(1).max(200).default(100),
  offset: z.number().int().min(0).default(0),
})

export type FileListQuery = z.infer<typeof FileListQuerySchema>

/**
 * 文件大小校验（用于客户端/服务端一致校验）
 */
export function validateFileSize(size: number): boolean {
  return size > 0 && size <= MAX_FILE_SIZE
}
