import { FreshContext, Handlers } from "$fresh/server.ts";
import { getImageContent } from "@lib/image.ts";
import { SILVERBULLET_SERVER } from "@lib/env.ts";
import { createLogger } from "@lib/log.ts";
import { isLocalImage } from "@lib/string.ts";

const log = createLogger("api/image");

// Constants for image processing
const CONFIG = {
  maxDimension: 2048,
  minDimension: 1,
  acceptedMimeTypes: new Set([
    "image/jpeg",
    "image/png",
    "image/webp",
    "image/gif",
  ]),
};

interface ImageParams {
  image: string;
  height: number;
  width: number;
}

/**
 * Validates and parses URL parameters for image processing
 */
function parseParams(reqUrl: URL): ImageParams | string {
  try {
    const image = reqUrl.searchParams.get("image")?.replace(/^\//, "");
    if (!image) {
      return "Missing 'image' query parameter.";
    }

    // Parse dimensions with defaults
    const height = Math.floor(Number(reqUrl.searchParams.get("height")) || 0);
    const width = Math.floor(Number(reqUrl.searchParams.get("width")) || 0);

    // Validate dimensions
    if (height < 0 || width < 0) {
      return "Negative height or width is not supported.";
    }

    if (height > CONFIG.maxDimension || width > CONFIG.maxDimension) {
      return `Width and height cannot exceed ${CONFIG.maxDimension}.`;
    }

    // If dimensions are provided, ensure they're not too small
    if (
      (height > 0 && height < CONFIG.minDimension) ||
      (width > 0 && width < CONFIG.minDimension)
    ) {
      return `Dimensions must be at least ${CONFIG.minDimension} pixel.`;
    }

    return { image, height, width };
  } catch (error) {
    log.error("Error parsing parameters:", error);
    return "Invalid parameters provided.";
  }
}

const GET = async (
  req: Request,
  _ctx: FreshContext,
): Promise<Response> => {
  try {
    const url = new URL(req.url);
    const params = parseParams(url);

    if (typeof params === "string") {
      return new Response(params, {
        status: 400,
        headers: { "Content-Type": "text/plain" },
      });
    }

    const imageUrl = isLocalImage(params.image)
      ? `${SILVERBULLET_SERVER}/${params.image.replace(/^\//, "")}`
      : params.image;

    log.debug("Processing image request:", { imageUrl, params });

    const image = await getImageContent(imageUrl, params);

    return new Response(image.content, {
      headers: {
        "Content-Type": image.mimeType,
      },
    });
  } catch (error) {
    log.error("Error processing image:", error);
    return new Response("Internal server error", {
      status: 500,
      headers: { "Content-Type": "text/plain" },
    });
  }
};

export const handler: Handlers = {
  GET,
};
