import { probeVideoDurationSeconds } from "@/lib/probe-video-duration"; /** * SH-116 client-confirmed media contract on the vendor portal: photos up to * 10 MB (JPEG/PNG/HEIC), videos up to 100 MB and 90 seconds (MP4/MOV). * PDF documents keep the previous 10 MB document cap. */ const MAX_DOCUMENT_BYTES = 10 * 1024 * 1024; const MAX_PHOTO_BYTES = 10_000_000; const MAX_VIDEO_BYTES = 100_000_000; const MAX_VIDEO_DURATION_SECONDS = 90; const UNSUPPORTED_TYPE_MESSAGE = "Only PDF, JPG, PNG, HEIC, MP4, and MOV files are allowed."; type VendorUploadKind = "document" | "photo" | "video"; function resolveKind(file: File): VendorUploadKind | null { const extension = file.name.toLowerCase().split(".").pop() ?? ""; const mime = file.type.toLowerCase(); if (mime.startsWith("video/") || extension === "mp4" || extension === "mov") return "video"; if (mime.startsWith("image/") || ["jpg", "jpeg", "png", "heic"].includes(extension)) { return "photo"; } if (mime === "application/pdf" || extension === "pdf") return "document"; return null; } export async function validateVendorDocument(file: File): Promise { const kind = resolveKind(file); if (!kind) { return UNSUPPORTED_TYPE_MESSAGE; } if (kind === "photo" && file.size > MAX_PHOTO_BYTES) { return "Photos must be 10 MB or smaller."; } if (kind === "video") { if (file.size > MAX_VIDEO_BYTES) { return "Videos must be 100 MB or smaller."; } // Duration is checked client-side only; unreadable metadata never blocks. const duration = await probeVideoDurationSeconds(file); if (duration != null && duration > MAX_VIDEO_DURATION_SECONDS) { return `Videos must be ${MAX_VIDEO_DURATION_SECONDS} seconds or shorter.`; } } if (kind === "document" && file.size > MAX_DOCUMENT_BYTES) { return "Files must be 10 MB or smaller."; } return undefined; }