<template>
  <view class="generate-image-container">
	 
    <!-- 插槽用于放置需要生成图片的内容 -->
    <view class="content-container" ref="captureElement" v-if="!generatedImage">
      <slot></slot>
    </view>
    
    <!-- 生成的图片预览 -->
    <view class="preview-container" v-if="generatedImage && showPreview">
      <image :src="generatedImage" mode="widthFix" class="preview-image"></image>
    </view>
  </view>
</template>

<script>
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';

export default {
  name: 'GenerateImage',
  props: {
    // 是否显示预览
    showPreview: {
      type: Boolean,
      default: true
    },
    // 二维码内容（如果不需要二维码可不传）
    qrCodeContent: {
      type: String,
      default: ''
    },
    // 二维码大小
    qrCodeSize: {
      type: Number,
      default: 110
    },
    // 二维码容器样式
    qrCodeContainerStyle: {
      type: Object,
      default: () => ({
        position: 'absolute',
        bottom: '10rpx',
        right: '10rpx',
        background: '#fff',
        padding: '10rpx',
        borderRadius: '10rpx',
        boxShadow: '0 0 10rpx rgba(0,0,0,0.1)'
      })
    },
    // 存储的key，用于缓存
    storageKey: {
      type: String,
      default: 'savedGeneratedImage'
    },
    // 最大重试次数
    maxRetryCount: {
      type: Number,
      default: 3
    },
    // 是否启用缓存
    enableCache: {
      type: Boolean,
      default: true
    },
    // 图片质量（0-1）
    quality: {
      type: Number,
      default: 0.7
    }
  },
  data() {
    return {
      generatedImage: '', // 生成的图片
      isContentReady: false, // 内容是否准备就绪
      retryCount: 0 // 重试次数
    }
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      // 检查是否有缓存的图片
      if (this.enableCache) {
        const cachedImage = uni.getStorageSync(this.storageKey);
        if (cachedImage) {
          this.generatedImage = cachedImage;
          this.$emit('success', cachedImage);
          return;
        }
      }
      
      // 重置状态
      this.isContentReady = false;
      this.retryCount = 0;
      
      // 模拟内容加载完成
      this.handleContentReady();
    },
    
    // 内容准备就绪
    handleContentReady() {
      this.isContentReady = true;
      this.generateImage();
    },
    
    // 生成图片
    async generateImage() {
      try {
        this.$emit('start');
        
        // 如果有二维码内容，先生成二维码
        if (this.qrCodeContent) {
          await this.makeQrcode();
          await new Promise(resolve => setTimeout(resolve, 500));
        }
        
        // 执行截图
        await this.captureImage();
        
        this.$emit('success', this.generatedImage);
      } catch (error) {
        console.error('生成图片失败:', error);
        this.$emit('error', error);
        this.retryGenerate();
      }
    },
    
    // 重试机制
    retryGenerate() {
      if (this.retryCount < this.maxRetryCount) {
        this.retryCount++;
        const delay = 1000 * this.retryCount;
        
        setTimeout(() => {
          this.generateImage();
        }, delay);
      } else {
        this.$emit('fail', '生成图片失败，请稍后再试');
      }
    },
    
    // 生成二维码
    makeQrcode() {
      return new Promise((resolve, reject) => {
        if (!this.qrCodeContent) {
          resolve();
          return;
        }
        
        // 创建实例
        const qr = new UQRCode();
        
        // 设置二维码内容
        qr.data = this.qrCodeContent;
        qr.size = this.qrCodeSize;
        qr.foregroundColor = '#000000';
        qr.backgroundColor = '#FFFFFF';
        qr.margin = 10;
        qr.errorCorrectLevel = UQRCode.errorCorrectLevel.H;
        
        try {
          // 调用制作二维码方法
          qr.make();
          
          // 获取canvas上下文
          const ctx = uni.createCanvasContext('qrcode', this);
          
          // 清空画布
          ctx.clearRect(0, 0, this.qrCodeSize, this.qrCodeSize);
          
          // 将二维码绘制到canvas上
          qr.canvasContext = ctx;
          qr.drawCanvas();
          
          // 绘制完成
          ctx.draw(true, () => {
            resolve();
          });
        } catch (err) {
          reject(err);
        }
      });
    },
    
    // 截图方法
    async captureImage() {
      try {
        // 获取DOM元素
        const element = this.$refs.captureElement.$el;
        
        // 调用工具函数生成图片
        const imageData = await elementToImage(element);
        
        // 压缩图片
        const compressedImage = await this.compressImage(imageData);
        
        this.generatedImage = compressedImage;
        
        // 缓存图片
        if (this.enableCache) {
          uni.setStorageSync(this.storageKey, compressedImage);
        }
      } catch (error) {
        throw error;
      }
    },
    
    // 压缩图片
    compressImage(base64) {
      return new Promise((resolve) => {
        const img = new Image();
        img.src = base64;
        img.onload = () => {
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          
          // 设置压缩后的宽高
          const maxWidth = 800;
          const maxHeight = 1200;
          let width = img.width;
          let height = img.height;
          
          if (width > maxWidth) {
            height *= maxWidth / width;
            width = maxWidth;
          }
          
          if (height > maxHeight) {
            width *= maxHeight / height;
            height = maxHeight;
          }
          
          canvas.width = width;
          canvas.height = height;
          ctx.drawImage(img, 0, 0, width, height);
          
          // 降低质量
          resolve(canvas.toDataURL('image/jpeg', this.quality));
        };
      });
    },
    
    // 保存图片到相册
    saveImage() {
      if (!this.generatedImage) {
        this.$emit('error', '没有可保存的图片');
        return;
      }
      
      if (uni.downloadFile) {
        uni.downloadFile({
          url: this.generatedImage,
          success: (res) => {
            if (res.statusCode === 200) {
              uni.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: () => {
                  this.$emit('save-success');
                },
                fail: (err) => {
                  this.$emit('save-error', err);
                }
              });
            }
          },
          fail: (err) => {
            this.$emit('save-error', err);
          }
        });
      } else {
        // H5环境下的处理方式
        const link = document.createElement('a');
        link.href = this.generatedImage;
        link.download = 'generated-image.png';
        link.click();
        this.$emit('save-success');
      }
    },
    
    // 重新生成图片
    regenerate() {
      if (this.enableCache) {
        uni.removeStorageSync(this.storageKey);
      }
      this.generatedImage = '';
      this.init();
    },
    
    // 获取生成的图片
    getGeneratedImage() {
      return this.generatedImage;
    }
  }
}
</script>

<style lang="scss" scoped>
.generate-image-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  position: relative;
  .dropdown-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 100;
  }
  
  .content-container {
    width: 100%;
    height: auto;
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: #fff;
	border-radius: 16rpx 16rpx 0 0;
	box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
	z-index: 110;
	transform: translateY(100%);
	transition: transform 0.3s ease;
  }
  
  .preview-container {
    flex: 1;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    
    .preview-image {
      height: 100%;
      width: auto;
      object-fit: contain;
    }
  }
}
</style>