/**
 * 通用 zod 校验 schema 与 helpers
 *
 * 所有表单的字段校验集中在此处，避免在组件中散落硬编码字符串与正则。
 * 新增字段类型时统一在此扩展，组件只组合使用。
 */
import { z } from "zod";

// 中国大陆手机号
export const phoneCN = z
  .string({ required_error: "请输入联系电话" })
  .trim()
  .regex(/^1[3-9]\d{9}$/, "请输入有效的手机号");

// 必填的非空字符串
export const requiredString = (label: string, max = 500) =>
  z
    .string({ required_error: `请填写${label}` })
    .trim()
    .min(1, `请填写${label}`)
    .max(max, `${label}不能超过 ${max} 个字符`);

// 详细描述（多行文本）
export const description = (min = 5, max = 1000) =>
  z
    .string({ required_error: "请填写描述" })
    .trim()
    .min(min, `描述至少 ${min} 个字符`)
    .max(max, `描述不能超过 ${max} 个字符`);

// 选项：必选枚举
export const requiredEnum = <T extends [string, ...string[]]>(
  values: T,
  message = "请选择一项",
) => z.enum(values, { required_error: message, invalid_type_error: message });

// 图片文件数组（带尺寸/类型/数量校验）
export const imageFiles = (opts?: { maxCount?: number; maxSizeMB?: number }) => {
  const maxCount = opts?.maxCount ?? 6;
  const maxSize = (opts?.maxSizeMB ?? 5) * 1024 * 1024;
  return z
    .array(z.instanceof(File))
    .max(maxCount, `最多上传 ${maxCount} 张图片`)
    .refine(
      (files) => files.every((f) => f.type.startsWith("image/")),
      "仅支持图片文件",
    )
    .refine(
      (files) => files.every((f) => f.size <= maxSize),
      `单张图片不能超过 ${opts?.maxSizeMB ?? 5}MB`,
    );
};
