import { image } from '@kit.ImageKit';
import util from '@ohos.util';

export class CircleImageProcessor {

  /**
   * 将正方形图片转换为真正的圆形图片（带透明背景）
   */
  static async createTrueCircleImage(squarePm: PixelMap): Promise<PixelMap> {
    const info = await squarePm.getImageInfo();
    const size = Math.min(info.size.width, info.size.height);

    console.info(`Creating true circle image, size: ${size}x${size}`);

    // 1. 读取原始像素（BGRA格式）
    const originalBuffer = new ArrayBuffer(squarePm.getPixelBytesNumber());
    await squarePm.readPixelsToBuffer(originalBuffer);
    const originalPixels = new Uint8ClampedArray(originalBuffer);

    // 2. 创建新的RGBA像素数组（支持透明度）
    const pixelBuffer = new Uint8ClampedArray(size * size * 4);

    const radius = size / 2;
    const centerX = radius;
    const centerY = radius;
    const radiusSq = radius * radius;

    // 3. 遍历每个像素，创建圆形遮罩
    for (let y = 0; y < size; y++) {
      for (let x = 0; x < size; x++) {
        const dx = x - centerX;
        const dy = y - centerY;
        const distSq = dx * dx + dy * dy;

        const srcIdx = (y * size + x) * 4;
        const dstIdx = (y * size + x) * 4;

        if (distSq <= radiusSq) {
          // 圆形区域内：复制像素并转换 BGRA -> RGBA
          // 同时进行抗锯齿处理（边缘半透明）
          const distance = Math.sqrt(distSq);
          let alpha = 255; // 完全不透明

          // 边缘抗锯齿：距离半径3像素内的区域逐渐透明
          if (distance > radius - 3) {
            const edgeDistance = radius - distance;
            alpha = Math.max(0, Math.min(255, Math.floor((edgeDistance / 3) * 255)));
          }

          pixelBuffer[dstIdx] = originalPixels[srcIdx + 2];     // R
          pixelBuffer[dstIdx + 1] = originalPixels[srcIdx + 1]; // G
          pixelBuffer[dstIdx + 2] = originalPixels[srcIdx];     // B
          pixelBuffer[dstIdx + 3] = alpha;                      // A（带抗锯齿）
        } else {
          // 圆形区域外：完全透明
          pixelBuffer[dstIdx] = 0;     // R
          pixelBuffer[dstIdx + 1] = 0; // G
          pixelBuffer[dstIdx + 2] = 0; // B
          pixelBuffer[dstIdx + 3] = 0; // A（完全透明）
        }
      }
    }

    // 4. 创建新的PixelMap（RGBA_8888支持透明度）
    const opts: image.InitializationOptions = {
      editable: true,
      pixelFormat: image.PixelMapFormat.RGBA_8888,
      size: { height: size, width: size },
      alphaType: image.AlphaType.PREMUL // 预乘alpha，透明度效果更好
    };

    console.info('Circle image created successfully');
    return await image.createPixelMap(pixelBuffer.buffer, opts);
  }

  /**
   * 从矩形图片创建圆形图片
   */
  static async cropAndCreateCircle(sourcePm: PixelMap, cropRegion: image.Region): Promise<PixelMap> {
    // 1. 先裁剪为正方形
    const squarePm = await CircleImageProcessor.cropToSquare(sourcePm, cropRegion);

    // 2. 转换为圆形
    const circlePm = await CircleImageProcessor.createTrueCircleImage(squarePm);

    // 3. 清理临时资源
    squarePm.release();

    return circlePm;
  }

  /**
   * 裁剪为正方形
   */
  private static async cropToSquare(sourcePm: PixelMap, region: image.Region): Promise<PixelMap> {
    // 确保是正方形区域
    const squareSize = Math.min(region.size.width, region.size.height);
    const squareRegion: image.Region = {
      x: region.x + (region.size.width - squareSize) / 2,
      y: region.y + (region.size.height - squareSize) / 2,
      size: { width: squareSize, height: squareSize }
    };

    // 深拷贝PixelMap然后裁剪
    const copyPm = await CircleImageProcessor.copyPixelMap(sourcePm);
    copyPm.cropSync(squareRegion);
    return copyPm;
  }

  /**
   * 深拷贝PixelMap
   */
  private static async copyPixelMap(pm: PixelMap): Promise<PixelMap> {
    const imageInfo: image.ImageInfo = await pm.getImageInfo();
    const buffer: ArrayBuffer = new ArrayBuffer(pm.getPixelBytesNumber());
    await pm.readPixelsToBuffer(buffer);

    const opts: image.InitializationOptions = {
      editable: true,
      pixelFormat: image.PixelMapFormat.BGRA_8888,
      size: { height: imageInfo.size.height, width: imageInfo.size.width }
    };
    return image.createPixelMap(buffer, opts);
  }
}