import { openStore } from "@/lib/data/store";

/** Where the mark sits, as a sharp gravity value. */
const GRAVITY: Record<string, string> = {
  "Bottom right": "southeast",
  "Bottom left": "southwest",
  "Top right": "northeast",
  "Top left": "northwest",
  Centre: "center",
};

/**
 * Stamps a photo with the site's watermark, when one is configured.
 *
 * Returns the original bytes unchanged if watermarking is off, the image
 * isn't a photo, or anything goes wrong — a failed watermark should never
 * cost someone their upload.
 */
export async function applyWatermark(
  bytes: Buffer,
  mime: string
): Promise<Buffer> {
  if (!mime.startsWith("image/") || mime === "image/gif") return bytes;

  const store = await openStore();
  const s = await store.settings();
  if (s.watermarkEnabled !== true) return bytes;

  try {
    const sharp = (await import("sharp")).default;
    const opacity = Math.min(100, Math.max(1, Number(s.watermarkOpacity ?? 60))) / 100;
    const gravity = GRAVITY[String(s.watermarkPosition ?? "Bottom right")] ?? "southeast";
    const offsetX = Number(s.watermarkXOffset ?? 20);
    const offsetY = Number(s.watermarkYOffset ?? 20);

    const image = sharp(bytes);
    const meta = await image.metadata();
    const width = meta.width ?? 0;
    if (width < 200) return bytes; // too small to mark legibly

    let overlay: Buffer;

    if (String(s.watermarkType ?? "Site name") === "Image" && s.watermarkIcon) {
      // A supplied image, scaled to a fraction of the photo's width.
      const iconPath = String(s.watermarkIcon);
      const source = iconPath.startsWith("/media/")
        ? path.join(UPLOAD_DIR, iconPath.replace("/media/", ""))
        : iconPath;
      overlay = await sharp(source)
        .resize({ width: Math.round(width * 0.18) })
        .composite([
          {
            input: Buffer.from([255, 255, 255, Math.round(opacity * 255)]),
            raw: { width: 1, height: 1, channels: 4 },
            tile: true,
            blend: "dest-in",
          },
        ])
        .png()
        .toBuffer();
    } else {
      // The site's name, drawn as text.
      const label = String(s.siteName ?? "").trim() || "XRcoin";
      const size = Math.max(14, Math.round(width * 0.035));
      const escaped = label.replace(/[<>&]/g, "");
      overlay = Buffer.from(
        `<svg width="${escaped.length * size * 0.62}" height="${size * 1.5}">
           <text x="0" y="${size}" font-family="Inter, sans-serif"
                 font-size="${size}" font-weight="700"
                 fill="#ffffff" fill-opacity="${opacity}">${escaped}</text>
         </svg>`
      );
    }

    return await image
      .composite([{ input: overlay, gravity, top: undefined, left: undefined }])
      .toBuffer()
      .catch(() => bytes);
  } catch {
    // Any failure leaves the photo as it was.
    return bytes;
  }
}

import path from "path";
import { UPLOAD_DIR } from "./storage";
