/**
 * پردازش و یکپارچه‌سازی خودکار همه عکس‌های آپلودی پنل (محصول، بنر، کاور و متن مقاله).
 *
 * هر عکس با هر فرمت (JPG، PNG، WebP، AVIF، HEIC/HEIF، GIF، TIFF) و هر ابعاد و نسبتی، بلافاصله در سرور:
 * ۱) نوع فایل از روی محتوای واقعی تشخیص داده می‌شود، نه پسوند یا هدر مرورگر
 * ۲) جهت عکس بر اساس EXIF درست و سپس همه متادیتا (EXIF، موقعیت مکانی) حذف می‌شود
 * ۳) به کادر مربع ۱:۱ تبدیل می‌شود: عکس بدون کشیدگی و بدون برش، با حفظ تناسب، وسط کادر قرار می‌گیرد
 *    و زمینه خاکستری یکدست کارت‌ها (SQUARE_BACKGROUND) می‌گیرد؛ زمینه سفید عکس‌های استودیویی و زمینه شفاف PNG
 *    هم به همین خاکستری برده می‌شود تا همه کارت‌ها یک شکل باشند (جزئیات در image-square.ts)
 * ۴) سه اندازه WebP مربع (۴۰۰، ۸۰۰ و ۱۶۰۰ پیکسل) ساخته و ذخیره می‌شود؛ فایل اصلی نگه داشته نمی‌شود
 */
import "server-only";
import sharp from "sharp";
import { randomBytes } from "node:crypto";
import { IMAGE_WIDTHS, imageSrc } from "@/lib/media";
import { storage } from "@/integrations/storage";
import { MAX_PIXELS, squarePlanFor, squareWebp } from "./image-square";

export { SQUARE_BACKGROUND } from "./image-square";

export const MAX_UPLOAD_BYTES = 10 * 1024 * 1024;
const ALLOWED_FORMATS = new Set(["jpeg", "png", "webp", "avif", "heif", "gif", "tiff"]);
const MIN_SIDE = 50; // فقط برای رد کردن فایل‌های خراب/آیکون؛ عکس کوچک بزرگ‌نمایی می‌شود

export class ImageError extends Error {}

/** ذخیره عکس در سه اندازه WebP مربع؛ خروجی: آدرس پایه (بدون پسوند اندازه) برای ذخیره در دیتابیس */
export async function storeImage(folder: string, file: File): Promise<string> {
  if (file.size === 0) throw new ImageError("فایل خالی است");
  if (file.size > MAX_UPLOAD_BYTES) throw new ImageError("حجم عکس باید کمتر از ۱۰ مگابایت باشد");

  const input = Buffer.from(await file.arrayBuffer());
  const meta = await sharp(input, { limitInputPixels: MAX_PIXELS }).metadata().catch(() => undefined);
  if (!meta?.format || !ALLOWED_FORMATS.has(meta.format)) throw new ImageError("فرمت فایل پشتیبانی نمی‌شود (JPG، PNG، WebP، AVIF، HEIC، GIF یا TIFF)");
  if ((meta.width ?? 0) < MIN_SIDE || (meta.height ?? 0) < MIN_SIDE) throw new ImageError("عکس خیلی کوچک است (حداقل ۵۰ پیکسل)");

  const key = `${folder}/${randomBytes(9).toString("hex")}`;
  const plan = await squarePlanFor(input);
  const outputs = await Promise.all(IMAGE_WIDTHS.map(async (w) => ({ key: imageSrc(key, w), body: await squareWebp(input, w, plan) })));
  const store = storage();
  await Promise.all(outputs.map((o) => store.put(o.key, o.body, "image/webp")));
  return store.publicUrl(key);
}

export const storeProductImage = (productId: number, file: File) => storeImage(`products/${productId}`, file);

/** حذف همه اندازه‌های یک عکس از فضای ذخیره (خطا فقط ثبت می‌شود) */
export async function deleteStoredImage(baseUrl: string | null | undefined) {
  if (!baseUrl) return;
  const store = storage();
  const key = store.keyFromUrl(baseUrl);
  if (!key) return;
  await store.remove(IMAGE_WIDTHS.map((w) => imageSrc(key, w))).catch((e) => console.error("[images] حذف فایل ناموفق بود", e));
}
