import { image } from '@kit.ImageKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { util } from '@kit.ArkTS';
import { PickerUtil } from '@pura/picker_utils';
import componentSnapshot from '@ohos.arkui.componentSnapshot';
import { promptAction } from '@kit.ArkUI';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { subjectSegmentation } from '@kit.CoreVisionKit';
import { StickerItem } from '../viewmodel/LocalBean';
import buffer from '@ohos.buffer';
import fileIo from '@ohos.file.fs';
import { ToastUtils } from '../dialog/ToastUtils';


export class ImageUtils {
  private static readonly TAG: string = 'ImageUtils';

  /**
   * 压缩图片并保存到沙箱缓存目录
   * @param context 上下文
   * @param uri 原始图片URI (如 datashare:// 或 file://)
   * @param quality 压缩质量 (0-100)，默认 80
   * @returns 压缩后的沙箱文件路径
   */
  static async compressImage(context: common.Context, uri: string, quality: number = 80): Promise<string> {
    let file: fs.File | undefined;
    try {
      file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
      const imageSource: image.ImageSource = image.createImageSource(file.fd);
      const packingOptions: image.PackingOption = {
        format: 'image/jpeg',
        quality: quality
      };
      const imagePacker: image.ImagePacker = image.createImagePacker();
      const arrayBuffer: ArrayBuffer = await imagePacker.packing(imageSource, packingOptions);
      const fileName = `compress_${Date.now()}.jpg`;
      const cachePath = `${context.cacheDir}/${fileName}`;
      const cacheFile = fs.openSync(cachePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      fs.writeSync(cacheFile.fd, arrayBuffer);
      fs.closeSync(cacheFile);

      await imagePacker.release();
      await imageSource.release();

      console.info(ImageUtils.TAG, `图片压缩成功: ${cachePath}`);
      return `file://${cachePath}`; // 返回符合上传要求的 file 协议路径

    } catch (error) {
      const err = error as BusinessError;
      console.error(ImageUtils.TAG, `压缩失败: ${err.code} ${err.message}`);
      return uri; // 如果压缩失败，返回原路径尝试直接上传
    } finally {
      if (file) {
        fs.closeSync(file);
      }
    }
  }

  /**
   * 将图片 URI 转换为 Base64 字符串
   * @param uri 相册选择的 datashare:// 或沙箱路径
   */
  static async base64Image(uri: string): Promise<string> {
    const context = getContext();
    // 使用临时路径存储拷贝的文件
    const tempFileName = `${Date.now()}.jpg`;
    const destPath = `${context.cacheDir}/${tempFileName}`;

    let srcFile: fs.File | null = null;
    try {
      srcFile = fs.openSync(uri, fs.OpenMode.READ_ONLY);
      fs.copyFileSync(srcFile.fd, destPath);
      const base64Data = await ImageUtils.fileToBase64(destPath);
      fs.unlinkSync(destPath);

      return base64Data;
    } catch (err) {
      const error = err as BusinessError;
      console.error(`base64Image 转换失败: ${error.message}`);
      return "";
    } finally {
      if (srcFile) {
        fs.closeSync(srcFile);
      }
    }
  }

  static async pixelMapToBase64(pixelMap: image.PixelMap): Promise<string> {
    const imagePackerApi = image.createImagePacker();
    const packOptions: image.PackingOption = { format: 'image/png', quality: 100 };
    const data = await imagePackerApi.packing(pixelMap, packOptions);

    let base64Str = buffer.from(data).toString('base64');
    return `data:image/png;base64,${base64Str}`;
  }

  /**
   * 内部方法：读取文件转 Base64
   */
  private static async fileToBase64(filePath: string): Promise<string> {
    const file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
    const stat = fs.statSync(file.fd);
    const buffer = new ArrayBuffer(stat.size);
    fs.readSync(file.fd, buffer);
    fs.closeSync(file);

    const helper = new util.Base64Helper();
    return helper.encodeToStringSync(new Uint8Array(buffer));
  }


  /**
   * 保存图片到指定路径（用户自己选择）
   * @param pixelMap
   */
  static async savePixelMapToGallery(pixelMap: image.PixelMap) {
    const imagePacker: image.ImagePacker = image.createImagePacker();
    const packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 };

    try {
      const uris = await PickerUtil.savePhoto([`Rabbit_IMG_${Date.now()}.jpg`]);

      const targetUri: string = Array.isArray(uris) ? uris[0] : uris;

      if (!targetUri) {
        console.warn('用户取消保存或路径获取失败');
        return;
      }

      const buffer: ArrayBuffer = await imagePacker.packing(pixelMap, packOpts) as ArrayBuffer;
      const file = fs.openSync(targetUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      fs.writeSync(file.fd, buffer);
      fs.closeSync(file.fd);

      console.info('保存成功！路径: ' + targetUri);
    } catch (err) {
      console.error('保存过程中出错: ' + JSON.stringify(err));
    } finally {
      imagePacker.release();
    }
  }

  /**
   * 将图片（image.PixelMap）转成jpg、png、webp等
   * 保存图片到指定路径（用户自己选择）
   * @param pixelMap
   * @param format 支持: 'image/jpeg', 'image/png', 'image/webp'
   */
  static async saveFormatToGallery(pixelMap: image.PixelMap, format: string) {
    const imagePacker: image.ImagePacker = image.createImagePacker();
    const packOpts: image.PackingOption = { format: format, quality: 100 };

    try {
      const uris = await PickerUtil.savePhoto([`Rabbit_IMG_${Date.now()}.${format === 'image/jpeg' ? 'jpg' : format.substring(6)}`]);

      const targetUri: string = Array.isArray(uris) ? uris[0] : uris;

      if (!targetUri) {
        console.warn('用户取消保存或路径获取失败');
        return;
      }

      const buffer: ArrayBuffer = await imagePacker.packing(pixelMap, packOpts) as ArrayBuffer;
      const file = fs.openSync(targetUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      fs.writeSync(file.fd, buffer);
      fs.closeSync(file.fd);


      ToastUtils.normalToast({ message: '图片已保存' });
    } catch (err) {
      ToastUtils.normalToast({ message: '保存失败' });
    } finally {
      imagePacker.release();
    }
  }

  /**
   * 将图片（image.PixelMap）转成SVG
   * @param pixelMap
   */
  static async saveSvgToGallery(pixelMap: image.PixelMap) {
    let imagePackerApi = image.createImagePacker();
    const info = await pixelMap.getImageInfo();
    const width = info.size.width;
    const height = info.size.height;

    const uris = await PickerUtil.savePhoto([`Rabbit_IMG_${Date.now()}.svg`]);
    const targetUri: string = Array.isArray(uris) ? uris[0] : uris;
    if (!targetUri) {
      console.warn('用户取消保存或路径获取失败');
      return;
    }

    const packOptions: image.PackingOption = {
      format: 'image/png',
      quality: 100
    };
    const arrayBuffer = await imagePackerApi.packing(pixelMap, packOptions);

    // 将二进制数据转为 Base64 字符串，buffer.from().toString('base64') 默认不换行的 (等同于 NO_WRAP)
    const base64Data = buffer.from(arrayBuffer).toString('base64');

    // 构建 SVG 内容
    const svgContent = `<?xml version="1.0" encoding="UTF-8"?>
<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
    <image width="${width}" height="${height}"
           xlink:href="data:image/png;base64,${base64Data}"
           href="data:image/png;base64,${base64Data}" />
</svg>`;


    try {
      let file = fileIo.openSync(targetUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE | fileIo.OpenMode.TRUNC);
      fileIo.writeSync(file.fd, svgContent);
      fileIo.closeSync(file);
      ToastUtils.normalToast({ message: '图片已保存' });
    } catch (err) {
      ToastUtils.normalToast({ message: '保存失败' });
    }
  }


  /**
   * 保存图片（通过布局ID保存图片）
   * 注意：id为控件的ID
   */
  static async saveImageForID(id: string): Promise<boolean> {
    try {
      let pixelMap = await componentSnapshot.get(id);

      if (pixelMap) {
        await ImageUtils.savePixelMapToGallery(pixelMap);
        ToastUtils.normalToast({ message: '图片已保存' });

        return true;
      }else{
        return false;
      }
    } catch (err) {
      console.error(`快照捕获失败: ${JSON.stringify(err)}`);
      return false;
    }
  }

  /**
   * 打开图库（仅可选单张图片）
   */
  static async openGallery(): Promise<StickerItem|null> {
    let file: fs.File | null = null;
    try {
      const photoPicker = new photoAccessHelper.PhotoViewPicker();
      const options = new photoAccessHelper.PhotoSelectOptions();
      options.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
      options.maxSelectNumber = 1;

      const result: photoAccessHelper.PhotoSelectResult = await photoPicker.select(options);
      if (result.photoUris.length === 0) return null;

      const uri: string = result.photoUris[0];
      file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
      const imageSource: image.ImageSource = image.createImageSource(file.fd);
      const pixelMap: image.PixelMap = await imageSource.createPixelMap();
      let newItem = new StickerItem(pixelMap,0);

      return newItem;
    } catch (err) {
      ToastUtils.normalToast({ message: '获取图片失败！' });
      return null;
    } finally {
      if (file) fs.closeSync(file);
    }
  }

  /**
   * 打开图库（仅可选单张图片-抠图）
   */
  static async openCutoutGallery(): Promise<StickerItem|null> {
    let file: fs.File | null = null;
    try {
      const photoPicker = new photoAccessHelper.PhotoViewPicker();
      const options = new photoAccessHelper.PhotoSelectOptions();
      options.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
      options.maxSelectNumber = 1;

      const result: photoAccessHelper.PhotoSelectResult = await photoPicker.select(options);
      if (result.photoUris.length === 0) return null;

      const uri: string = result.photoUris[0];
      file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
      const imageSource: image.ImageSource = image.createImageSource(file.fd);
      const pixelMap: image.PixelMap = await imageSource.createPixelMap();

      ToastUtils.normalToast({ message: '抠图中...' });

      await subjectSegmentation.init();
      const visionInfo: subjectSegmentation.VisionInfo = { pixelMap: pixelMap };
      const config: subjectSegmentation.SegmentationConfig = {
        enableSubjectForegroundImage: true
      };

      const segResult: subjectSegmentation.SegmentationResult =
        await subjectSegmentation.doSegmentation(visionInfo, config);
      if (segResult && segResult.fullSubject && segResult.fullSubject.foregroundImage) {
        const pixelMap = segResult.fullSubject.foregroundImage;
        let newItem = new StickerItem(pixelMap,0);

        await subjectSegmentation.release();
        return newItem;
      }else{
        await subjectSegmentation.release();
        return null;
      }
    } catch (err) {
      ToastUtils.normalToast({ message: '抠图失败，请使用规范图片' });
      return null;
    } finally {
      if (file) fs.closeSync(file);
    }
  }

  /**
   * 打开图库（可选择多张图片）
   */
  static async openMultipleGallery(): Promise<image.PixelMap[]> {
      const pixelMaps: image.PixelMap[] = [];
      try {
        const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
        photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
        photoSelectOptions.maxSelectNumber = 10;
        const photoPicker = new photoAccessHelper.PhotoViewPicker();
        const photoSelectResult = await photoPicker.select(photoSelectOptions);

        if (!photoSelectResult || photoSelectResult.photoUris.length === 0) {
        return [];
      }
      for (const uri of photoSelectResult.photoUris) {
        let file: fs.File | null = null;
        try {
          file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
          const imageSource: image.ImageSource = image.createImageSource(file.fd);
          const decodingOptions: image.DecodingOptions = {
            editable: true,
            desiredPixelFormat: image.PixelMapFormat.RGBA_8888,
          };
          const pm = await imageSource.createPixelMap(decodingOptions);
          if (pm) {
            pixelMaps.push(pm);
          }
          imageSource.release();
        } catch (e) {
          console.error(`解析图片失败: ${uri}, 错误: ${JSON.stringify(e)}`);
        } finally {
          if (file) {
            fs.closeSync(file.fd);
          }
        }
      }
      return pixelMaps;
    } catch (err) {
      console.error('选择图片过程发生错误: ' + JSON.stringify(err));
      return [];
    }
  }

  /**
   * 获取 Resource 对应的 PixelMap
   * @param res Resource 对象
   * @returns PixelMap 对象
   */
  static async getPixelMapFromResource(res: Resource, context: common.UIAbilityContext): Promise<image.PixelMap> {
    const resourceMgr = context.resourceManager;
    const fileData = await resourceMgr.getMediaContent(res);
    const imageSource = image.createImageSource(fileData.buffer as ArrayBuffer);
    return await imageSource.createPixelMap({
      editable: true,
      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
    });
  }

  /**
   * 将 PixelMap 转换为 ImageSource
   * @param pixelMap 输入的位图对象
   * @returns 转换后的 ImageSource 对象
   */
  static async pixelMapToImageSource(pixelMap: image.PixelMap): Promise<image.ImageSource|undefined> {
    const imagePacker = image.createImagePacker();

    const packingOptions: image.PackingOption = {
      format: "image/jpeg",
      quality: 100
    };

    try {
      const buffer: ArrayBuffer = await imagePacker.packing(pixelMap, packingOptions);
      const imageSource: image.ImageSource = image.createImageSource(buffer);

      return imageSource;
    } catch (err) {
      console.error('转换失败: ' + JSON.stringify(err));
      return undefined;
    } finally {
      imagePacker.release();
    }
  }

}
