import { prisma } from "@/lib/prisma";

/** Upload policy — the central credential decides the image file-size /
    dimension limits and the document (PDF) size limit that institutions'
    uploads must respect (profile photos, scans, ticket attachments…). */

export const UPLOAD_IMAGE_MAX_KB = "uploadImageMaxKb";
export const UPLOAD_IMAGE_MAX_DIM = "uploadImageMaxDim";
export const UPLOAD_DOC_MAX_KB = "uploadDocMaxKb";

export interface UploadPolicy {
  imageMaxKb: number;
  imageMaxDim: number;
  docMaxKb: number;
}

export const DEFAULT_UPLOAD_POLICY: UploadPolicy = {
  imageMaxKb: 2048,
  imageMaxDim: 1024,
  docMaxKb: 2048,
};

export function clampInt(v: unknown, min: number, max: number, fallback: number): number {
  const n = Number(v);
  if (!Number.isFinite(n)) return fallback;
  return Math.min(max, Math.max(min, Math.round(n)));
}

export async function getUploadPolicy(): Promise<UploadPolicy> {
  const rows = await prisma.platformSetting.findMany({
    where: { key: { in: [UPLOAD_IMAGE_MAX_KB, UPLOAD_IMAGE_MAX_DIM, UPLOAD_DOC_MAX_KB] } },
    select: { key: true, value: true },
  });
  const map = new Map(rows.map((r) => [r.key, r.value]));
  return {
    imageMaxKb: clampInt(map.get(UPLOAD_IMAGE_MAX_KB), 50, 20480, DEFAULT_UPLOAD_POLICY.imageMaxKb),
    imageMaxDim: clampInt(map.get(UPLOAD_IMAGE_MAX_DIM), 128, 4096, DEFAULT_UPLOAD_POLICY.imageMaxDim),
    docMaxKb: clampInt(map.get(UPLOAD_DOC_MAX_KB), 50, 20480, DEFAULT_UPLOAD_POLICY.docMaxKb),
  };
}

export async function setUploadPolicy(policy: UploadPolicy): Promise<UploadPolicy> {
  const entries: [string, string][] = [
    [UPLOAD_IMAGE_MAX_KB, String(policy.imageMaxKb)],
    [UPLOAD_IMAGE_MAX_DIM, String(policy.imageMaxDim)],
    [UPLOAD_DOC_MAX_KB, String(policy.docMaxKb)],
  ];
  for (const [key, value] of entries) {
    await prisma.platformSetting.upsert({
      where: { key },
      update: { value },
      create: { key, value },
    });
  }
  return policy;
}

/** max length of a base64 data URL (≈4/3 of the raw byte limit + header) */
export function maxDataUrlLength(maxKb: number): number {
  return Math.round(maxKb * 1024 * 1.4) + 128;
}
