export default class Haibao {
  constructor(width, height, color = '#fff') {
    this.canvas = document.createElement('canvas');
    this.ctx = this.canvas.getContext('2d', { alpha: true });
    this.canvas.width = width;
    this.canvas.height = height;
    // this.ctx.fillStyle = color;
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)

    this.zIndex = 0
    this.imagePromises = []
    this.images = []; // 存储待合成的图片信息
  }

  /**
   * 添加图片到合成队列（现在返回Promise）
   * @param {string|HTMLImageElement} image 图片URL或Image对象
   * @param {number} x 绘制X坐标
   * @param {number} y 绘制Y坐标
   * @returns {Promise} 图片加载完成的Promise
   */
  add (image, x, y, width = 'auto', height = 'auto', index) {
    this.zIndex++
    const zIndex = index ? index : this.zIndex
    const loadPromise = this._createLoadPromise(image).then(img => {
      this.images.push({ img, x, y, width, height, zIndex });
    });

    this.imagePromises.push(loadPromise);
    return loadPromise;
  }
  text (text, x, y, opts) {
    const { font = '16px sans-serif', color = '#000', align = 'center' } = opts || {};
    this.ctx.font = font;
    this.ctx.fillStyle = color;

    const drawText = (text, x, y) => {
      this.ctx.fillText(text, x, y);
    };
    const totalWidth = this.ctx.measureText(text).width;

    if (align === 'center') {
      x -= totalWidth / 2;
    }

    drawText(text, x, y);

    return this
  }
  async draw (mask = 'source-over') {
    await Promise.all(this.imagePromises);

    // 绘制所有图片
    this.images.sort((a, b) => a.zIndex - b.zIndex)
    this.images.forEach(({ img, x, y, width, height, zIndex }, idx) => {
      const w = width === 'auto' ? img.width : width
      const h = height === 'auto' ? img.height : height
      this.ctx.drawImage(img, x, y, w, h);
      if (idx === 0) {
        this.ctx.globalCompositeOperation = mask
      } else {
        this.ctx.globalCompositeOperation = 'source-over'
      }
    });


    return this;
  }
  /**
   * 生成合成后的图片（返回Promise）
   * @returns {Promise<string>} 合成后的Base64图片数据
   */
  async generate ({ mimeType = 'image/jpeg', quality = .8 }) {
    const validTypes = ['image/png', 'image/jpeg', 'image/webp'];
    mimeType = validTypes.includes(mimeType) ? mimeType : 'image/png';
    quality = Math.min(1, Math.max(0, Number(quality))) || .8;

    const b64 = this.canvas.toDataURL(mimeType, quality)

    this.images.length = 0;
    this.imagePromises.length = 0;

    return b64

  }

  // 创建加载Promise（私有方法）
  _createLoadPromise (image) {
    if (typeof image === 'string') {
      return this._loadImageFromUrl(image);
    } else if (image instanceof HTMLImageElement) {
      return this._handleExistingImage(image);
    }
    return Promise.reject(new Error('Invalid image type'));
  }

  // 从URL加载图片
  _loadImageFromUrl (url) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'anonymous';
      img.src = url;
      img.onload = () => resolve(img);
      img.onerror = reject;
    });
  }

  // 处理已存在的Image对象
  _handleExistingImage (img) {
    return new Promise((resolve, reject) => {
      if (img.complete && img.naturalHeight !== 0) {
        resolve(img);
      } else {
        img.onload = () => resolve(img);
        img.onerror = reject;
      }
    });
  }
}