import type { ToolInput } from "../../core/io/input-types";
import type { ToolResult } from "../../core/io/output-types";
import type { ToolContext } from "../../core/plugins/plugin-types";
import type { ImageOptimizerOptions } from "./index";

export async function runImageOptimizer(
  input: ToolInput,
  options: ImageOptimizerOptions,
  context: ToolContext
): Promise<ToolResult> {
  const files = input.files;
  if (!files || files.length === 0) {
    throw new Error("No files provided for optimization.");
  }

  const results = [];
  let processed = 0;

  for (const file of files) {
    // Check if it's an image
    if (!file.type.startsWith("image/")) {
      throw new Error(`File ${file.name} is not an image.`);
    }

    context.reportProgress({
      percentage: (processed / files.length) * 100,
      message: `Optimizing ${file.name}...`,
    });

    const optimizedBlob = await optimizeImage(file, options);

    let ext = "jpg";
    if (options.format === "image/webp") ext = "webp";
    if (options.format === "image/png") ext = "png";

    const originalNameWithoutExt =
      file.name.substring(0, file.name.lastIndexOf(".")) || file.name;
    const newName = `${originalNameWithoutExt}_optimized.${ext}`;

    results.push({
      name: newName,
      mimeType: options.format,
      blob: optimizedBlob,
      sizeBefore: file.size,
      sizeAfter: optimizedBlob.size,
    });

    processed++;
  }

  context.reportProgress({ percentage: 100, message: "Done" });

  return {
    type: "files",
    files: results,
  };
}

function optimizeImage(
  file: File,
  options: ImageOptimizerOptions
): Promise<Blob> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);

    img.onload = () => {
      URL.revokeObjectURL(url);

      const canvas = document.createElement("canvas");
      const width = img.width;
      const height = img.height;

      // Optional: resize logic could go here based on max width/height options

      canvas.width = width;
      canvas.height = height;

      const ctx = canvas.getContext("2d");
      if (!ctx) {
        return reject(new Error("Could not get 2D context"));
      }

      ctx.drawImage(img, 0, 0, width, height);

      const quality = options.quality / 100;

      canvas.toBlob(
        (blob) => {
          if (blob) {
            resolve(blob);
          } else {
            reject(new Error("Failed to create blob from canvas"));
          }
        },
        options.format,
        quality
      );
    };

    img.onerror = () => {
      URL.revokeObjectURL(url);
      reject(new Error("Failed to load image for optimization"));
    };

    img.src = url;
  });
}
