package service

import (
	"bytes"
	"fmt"
	"image"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"

	"github.com/fogleman/gg"
	"github.com/skip2/go-qrcode"
	"github.com/zeromicro/go-zero/core/logx"
)

type ImageService struct {
	baseImagePath string
}

func NewImageService() *ImageService {
	return &ImageService{
		baseImagePath: "static/images", // 原图存放目录
	}
}

// ProcessImageWithQRCode 处理图片，在中间添加二维码
func (s *ImageService) ProcessImageWithQRCode(qrcodeType, qrcodeUrl string) ([]byte, string, error) {
	// 1. 根据qrcodeType确定使用哪张背景图
	var backgroundImageName string
	switch qrcodeType {
	case "promote":
		backgroundImageName = "tg_qrcode_1.png"
	case "invitation":
		backgroundImageName = "yq_qrcode_1.png"
	default:
		backgroundImageName = "tg_qrcode_1.png" // 默认使用第一张图片
	}

	// 2. 读取原图
	originalImagePath := filepath.Join(s.baseImagePath, backgroundImageName)
	originalImage, err := s.loadImage(originalImagePath)
	if err != nil {
		logx.Errorf("加载原图失败: %v, 图片路径: %s", err, originalImagePath)
		return nil, "", fmt.Errorf("加载原图失败: %v", err)
	}

	// 3. 获取原图尺寸
	bounds := originalImage.Bounds()
	imgWidth := bounds.Dx()
	imgHeight := bounds.Dy()

	// 4. 创建绘图上下文
	dc := gg.NewContext(imgWidth, imgHeight)

	// 5. 绘制原图作为背景
	dc.DrawImageAnchored(originalImage, imgWidth/2, imgHeight/2, 0.5, 0.5)

	// 6. 生成二维码（去掉白边）
	qrCode, err := qrcode.New(qrcodeUrl, qrcode.Medium)
	if err != nil {
		logx.Errorf("生成二维码失败: %v, 二维码内容: %s", err, qrcodeUrl)
		return nil, "", fmt.Errorf("生成二维码失败: %v", err)
	}
	// 禁用二维码边框，去掉白边
	qrCode.DisableBorder = true

	// 7. 根据二维码类型设置不同的尺寸和位置
	var qrSize int
	var qrX, qrY int

	switch qrcodeType {
	case "promote":
		// promote类型：精确设置二维码尺寸
		qrSize = 280 // 固定尺寸280px
		// 左下角位置：距左边和底边留一些边距
		qrX = 192                      // 距左边180px
		qrY = imgHeight - qrSize - 190 // 距底边100px

	case "invitation":
		// invitation类型：精确设置二维码尺寸
		qrSize = 360 // 固定尺寸320px
		// 中间偏上位置
		qrX = (imgWidth - qrSize) / 2 // 水平居中
		qrY = 555                     // 垂直位置200px

	default:
		// 默认（promote样式）
		qrSize = 280                   // 固定尺寸280px
		qrX = 200                      // 距左边180px
		qrY = imgHeight - qrSize - 200 // 距底边100px
	}

	// 8. 生成指定尺寸的二维码图片
	qrCodeImage := qrCode.Image(qrSize)

	// 9. 直接绘制二维码（不添加背景）
	dc.DrawImageAnchored(qrCodeImage, qrX+qrSize/2, qrY+qrSize/2, 0.5, 0.5)

	// 11. 输出为字节数组
	var buf bytes.Buffer
	err = png.Encode(&buf, dc.Image())
	if err != nil {
		logx.Errorf("编码图片失败: %v", err)
		return nil, "", fmt.Errorf("编码图片失败: %v", err)
	}

	logx.Infof("成功生成带二维码的图片，类型: %s, 二维码内容: %s, 图片尺寸: %dx%d, 二维码尺寸: %dx%d, 位置: (%d,%d)",
		qrcodeType, qrcodeUrl, imgWidth, imgHeight, qrSize, qrSize, qrX, qrY)

	return buf.Bytes(), "image/png", nil
}

// loadImage 加载图片文件
func (s *ImageService) loadImage(path string) (image.Image, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	// 尝试解码PNG
	img, err := png.Decode(file)
	if err != nil {
		// 如果PNG解码失败，重新打开文件尝试JPEG
		file.Close()
		file, err = os.Open(path)
		if err != nil {
			return nil, err
		}
		defer file.Close()

		img, err = jpeg.Decode(file)
		if err != nil {
			// 如果还是失败，使用通用解码器
			file.Close()
			file, err = os.Open(path)
			if err != nil {
				return nil, err
			}
			defer file.Close()

			img, _, err = image.Decode(file)
			if err != nil {
				return nil, err
			}
		}
	}

	return img, nil
}

// GetSupportedImageTypes 获取支持的图片类型列表
func (s *ImageService) GetSupportedImageTypes() []string {
	return []string{"promote", "invitation"}
}

// CheckImageExists 检查指定类型的背景图是否存在
func (s *ImageService) CheckImageExists(qrcodeType string) bool {
	var backgroundImageName string
	switch qrcodeType {
	case "promote":
		backgroundImageName = "tg_qrcode_1.png"
	case "invitation":
		backgroundImageName = "yq_qrcode_1.png"
	default:
		backgroundImageName = "tg_qrcode_1.png"
	}

	imagePath := filepath.Join(s.baseImagePath, backgroundImageName)
	_, err := os.Stat(imagePath)
	return err == nil
}
