package xibao

import (
	"image"
	"image/color"
	"log"
	"os"
	"strings"

	"git.lxtend.com/lixiangwuxian/imagedd/sprite"
	"git.lxtend.com/lixiangwuxian/imagedd/text2img"
	"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
	"git.lxtend.com/lixiangwuxian/qqbot/util"
	"github.com/fogleman/gg"
	"golang.org/x/image/font/opentype"
)

func GenerateCongratulationImage(text string, inputFile, outputFile string, isGood bool) {
	// 加载喜报背景图片
	im, err := gg.LoadImage(inputFile) // 需要提前准备的背景图片
	if err != nil {
		log.Print("无法加载喜报图片:", err)
		return
	}

	// 创建与背景图片大小相同的画布
	width := im.Bounds().Dx()
	height := im.Bounds().Dy()
	dc := gg.NewContext(width, height)

	// 将背景图片绘制到画布上
	dc.DrawImage(im, 0, 0)
	// 判断是否为图片
	if imgUrl, ok := isImageCQ(text); ok {
		filePath, err := util.DownloadFile(imgUrl, "/tmp/qqbot", false)
		if err != nil {
			log.Print("无法下载图片:", err)
			return
		}
		imC, err := gg.LoadImage(filePath)
		if err != nil {
			log.Print("无法加载图片:", err)
			return
		}
		widthC := imC.Bounds().Dx()
		heightC := imC.Bounds().Dy()
		dcC := gg.NewContext(widthC, heightC)
		dcC.DrawImage(imC, 0, 0)

		// 保存原始状态
		dcC.Push()

		scaleFactor := 1.0

		// 根据高度比例进行缩放
		if float64(heightC) > float64(height)/1.8 {
			scaleFactor = (float64(height) / 1.8) / float64(heightC)
		}

		// 根据宽度比例进行缩放
		if float64(widthC) > float64(width)/1.1 {
			scaleFactor = (float64(width) / 1.1) / float64(widthC)
		}

		// 针对宽高较小的情况进行缩放
		if heightC < height/5 && widthC < width/4 {
			if float64(widthC)*(float64(height)/5)/float64(heightC) > float64(width/4) {
				scaleFactor = (float64(height) / 5) / float64(heightC)
				// log.Print(fmt.Sprintf("图片高度过小，已缩放至高度的 %f 倍", scaleFactor))
			} else {
				scaleFactor = (float64(width) / 4) / float64(widthC)
				// log.Print(fmt.Sprintf("图片宽度过小，已缩放至宽度的 %f 倍", scaleFactor))
			}
		}

		// 应用缩放比例
		// 计算缩放后的图像尺寸
		newWidth := int(float64(widthC) * scaleFactor)
		newHeight := int(float64(heightC) * scaleFactor)

		// 创建一个新的上下文，使用缩放后的尺寸
		dcScaledC := gg.NewContext(newWidth, newHeight)

		// 将原始图像缩放并绘制到新的上下文中
		dcScaledC.Scale(scaleFactor, scaleFactor)
		dcScaledC.DrawImage(imC, 0, 0)

		// 在最终画布上绘制缩放后的图像
		dc.DrawImageAnchored(dcScaledC.Image(), width/2, height/2, 0.5, 0.5)
		dc.SavePNG(outputFile)
		return
	}

	// 设置字体和大小，字体文件需要自备，放在合适的路径
	// if err := dc.LoadFontFace("./resource/emoji.ttf", 96); err != nil {
	// 	log.Print("无法加载字体:", err)
	// 	return
	// }
	fontBytes, err := os.ReadFile("./resource/emoji.ttf")
	if err != nil {
		log.Printf("failed to load font: %v", err)
	}

	// 解析字体
	font, err := opentype.Parse(fontBytes)
	if err != nil {
		log.Printf("failed to parse font: %v", err)
	}

	// 设置字体大小和 DPI
	const fontSize = 48
	const dpi = 72

	// 创建 font.Face，用于渲染文本
	face, err := opentype.NewFace(font, &opentype.FaceOptions{
		Size:    fontSize,
		DPI:     dpi,
		Hinting: 0,
	})
	if err != nil {
		log.Printf("failed to create font face: %v", err)
		return
	}

	dc.SetFontFace(face)

	if err := dc.LoadFontFace("./resource/font.ttf", 96); err != nil {
		log.Print("无法加载字体:", err)
		return
	}

	if isGood {
		// 设置文本颜色为红色
		dc.SetRGB(0.8, 0, 0)
	} else {
		dc.SetRGB(0, 0, 0.8)
	}
	// 将文本按 \n 分割为多行
	lines := strings.Split(text, "\n")

	// 设置初始绘制的 y 位置，可以根据需要调整
	startY := float64(height) / 2
	lineHeight := 120.0 // 行高，可以根据字体大小调整

	// 居中绘制每一行
	for i, line := range lines {
		i = i - len(lines)/2
		x := float64(width) / 2
		y := startY + float64(i)*lineHeight
		dc.DrawStringAnchored(line, x, y, 0.5, 0.5)
	}

	// 将生成的图片保存为输出文件
	err = dc.SavePNG(outputFile)
	if err != nil {
		log.Print("无法保存生成的图片:", err)
	}
}

func GenerateCongratulationImageNew(text string, inputFile, outputFile string, isGood bool) {
	baseboard := sprite.NewNamedSpriteBoard()
	backgroundImageSprite, err := sprite.LoadSpriteFromFile("bg", inputFile)
	backgroundImageSprite.Index = 0
	if err != nil {
		log.Print("无法加载背景图片:", err)
		return
	}
	baseboard.AddSprite(backgroundImageSprite)
	var textColor color.RGBA
	if isGood {
		// 设置文本颜色为红色
		textColor = color.RGBA{R: 255 * 0.8, G: 0, B: 0, A: 255}
	} else {
		textColor = color.RGBA{R: 0, G: 0, B: 255 * 0.8, A: 255}
	}
	textImage, err := text2img.RenderTextToTrimmedImage(nil, text, 96, textColor, 0, 0)
	if err != nil {
		log.Print("无法渲染文本:", err)
		return
	}
	textSprite := sprite.Sprite{
		Name:     "text",
		Images:   []image.Image{textImage},
		Position: image.Point{X: backgroundImageSprite.GetCurrentImage().Bounds().Dx()/2 - textImage.Bounds().Dx()/2, Y: backgroundImageSprite.GetCurrentImage().Bounds().Dy()/2 - textImage.Bounds().Dy()/2},
		Index:    1,
	}
	baseboard.AddSprite(&textSprite)
	baseboard.SaveToApng(outputFile)
}

func isImageCQ(text string) (string, bool) {
	imgMsg := qq_message.ImageMessage{}
	if err := imgMsg.ParseMessage(text); err == nil {
		return imgMsg.Data.URL, true
	}
	return "", false
}
