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

function loadImage(url: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error("Failed to load image."));
    img.src = url;
  });
}

function canvasToBlob(
  canvas: HTMLCanvasElement,
  mimeType: string,
  quality = 0.95
): Promise<Blob> {
  return new Promise((resolve, reject) => {
    canvas.toBlob(
      (blob) => {
        if (blob) {
          resolve(blob);
        } else {
          reject(new Error("Failed to export image from canvas."));
        }
      },
      mimeType,
      quality
    );
  });
}

export async function runExifScrubber(
  input: ToolInput,
  _options: unknown,
  context: ToolContext
): Promise<ToolResult> {
  const files = input.files;
  if (!files || !Array.isArray(files) || files.length === 0) {
    throw new Error("No files uploaded for scrubbing.");
  }

  const outFiles = [];

  for (let i = 0; i < files.length; i++) {
    if (context.signal?.aborted) {
      throw new DOMException("Operation cancelled", "AbortError");
    }

    const file = files[i];
    context.reportProgress({
      percentage: (i / files.length) * 100,
      message: `Scrubbing metadata for ${file.name} (${i + 1}/${files.length})...`,
    });

    const url = URL.createObjectURL(file);
    try {
      const img = await loadImage(url);
      
      const canvas = document.createElement("canvas");
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;

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

      // Drawing to canvas discards EXIF headers
      ctx.drawImage(img, 0, 0);

      const mimeType = file.type || "image/jpeg";
      const blob = await canvasToBlob(canvas, mimeType);

      // Create new clean file name
      const dotIdx = file.name.lastIndexOf(".");
      const name = dotIdx !== -1
        ? `${file.name.substring(0, dotIdx)}_scrubbed${file.name.substring(dotIdx)}`
        : `${file.name}_scrubbed.jpg`;

      outFiles.push({
        name: name,
        mimeType: mimeType,
        blob: blob,
        sizeAfter: blob.size,
        sizeBefore: file.size,
      });
    } catch (err) {
      console.error(`Error scrubbing file ${file.name}:`, err);
      // Fallback or rethrow depending on strict requirements; we rethrow for safety
      throw err;
    } finally {
      URL.revokeObjectURL(url);
    }
  }

  context.reportProgress({ percentage: 100, message: "Metadata scrubbed successfully!" });
  return {
    type: "files",
    files: outFiles,
  };
}
