import { Jimp } from "jimp";
import path from "path";
import fs from "fs";

export async function compressImage(inputPath, quality = 80) {
  const ext = path.extname(inputPath).toLowerCase();
  const basename = path.basename(inputPath, ext);
  const outputDir = path.join(path.dirname(inputPath), "compressed");

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputPath = path.join(outputDir, `${basename}${ext}`);

  const image = await Jimp.read(inputPath);
  await image.write(outputPath, { quality });

  return outputPath;
}

export async function resizeImage(inputPath, sizes = [{ width: 800 }, { width: 400 }, { width: 200 }]) {
  const ext = path.extname(inputPath).toLowerCase();
  const basename = path.basename(inputPath, ext);
  const outputDir = path.join(path.dirname(inputPath), "resized");

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputs = [];

  for (const size of sizes) {
    const outputPath = path.join(outputDir, `${basename}_${size.width}w${ext}`);
    const image = await Jimp.read(inputPath);
    image.resize({ w: size.width });
    await image.write(outputPath);
    outputs.push(outputPath);
  }

  return outputs;
}

export async function addWatermark(inputPath, watermarkPath, position = "southeast") {
  const ext = path.extname(inputPath).toLowerCase();
  const basename = path.basename(inputPath, ext);
  const outputDir = path.join(path.dirname(inputPath), "watermarked");

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputPath = path.join(outputDir, `${basename}${ext}`);

  const image = await Jimp.read(inputPath);
  const watermark = await Jimp.read(watermarkPath);

  watermark.resize({ w: Math.floor(image.bitmap.width * 0.2) });

  const positions = {
    northwest: { x: 10, y: 10 },
    northeast: { x: image.bitmap.width - watermark.bitmap.width - 10, y: 10 },
    southwest: { x: 10, y: image.bitmap.height - watermark.bitmap.height - 10 },
    southeast: { x: image.bitmap.width - watermark.bitmap.width - 10, y: image.bitmap.height - watermark.bitmap.height - 10 }
  };

  const pos = positions[position];
  image.composite(watermark, pos.x, pos.y);
  await image.write(outputPath);

  return outputPath;
}

export async function unifyBackground(inputPath, bgColor = 0xFFFFFFFF) {
  const ext = path.extname(inputPath).toLowerCase();
  const basename = path.basename(inputPath, ext);
  const outputDir = path.join(path.dirname(inputPath), "background");

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputPath = path.join(outputDir, `${basename}${ext}`);

  const image = await Jimp.read(inputPath);
  const bg = new Jimp({ width: image.bitmap.width, height: image.bitmap.height, color: bgColor });
  bg.composite(image, 0, 0);
  await bg.write(outputPath);

  return outputPath;
}

export async function cropWithPadding(inputPath, targetWidth, targetHeight, bgColor = 0xFFFFFFFF) {
  const ext = path.extname(inputPath).toLowerCase();
  const basename = path.basename(inputPath, ext);
  const outputDir = path.join(path.dirname(inputPath), "cropped");

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  const outputPath = path.join(outputDir, `${basename}_${targetWidth}x${targetHeight}${ext}`);

  const image = await Jimp.read(inputPath);
  const aspectRatio = image.bitmap.width / image.bitmap.height;
  const targetRatio = targetWidth / targetHeight;

  if (aspectRatio > targetRatio) {
    image.resize({ w: targetWidth });
  } else {
    image.resize({ h: targetHeight });
  }

  const bg = new Jimp({ width: targetWidth, height: targetHeight, color: bgColor });
  const x = Math.floor((targetWidth - image.bitmap.width) / 2);
  const y = Math.floor((targetHeight - image.bitmap.height) / 2);
  bg.composite(image, x, y);
  await bg.write(outputPath);

  return outputPath;
}

export async function processImage(file, operation, params) {
  switch (operation) {
    case "compress":
      return await compressImage(file, params.quality);
    case "resize":
      return await resizeImage(file, params.sizes);
    case "watermark":
      return await addWatermark(file, params.watermarkPath, params.position);
    case "background":
      return await unifyBackground(file, params.bgColor);
    case "crop":
      return await cropWithPadding(file, params.width, params.height, params.bgColor);
    default:
      throw new Error(`未知操作: ${operation}`);
  }
}
