package models

import (
	"image"
	"io/ioutil"
	"log"
	"net/http"
	"regexp"

	"github.com/chai2010/webp"
	"github.com/disintegration/imaging"
	giftowebp "github.com/sizeofint/gif-to-webp"
)

// Image is a struct that contains the information of an image
type Image struct {
	image  image.Image
	format string
	data   []byte
}

// 初始化图片
func (img *Image) Init(content string) {
	if len(regexp.MustCompile(`image.gameuiux.cn`).FindStringSubmatch(content)) > 0 {
		key := regexp.MustCompile(`^https?://image.gameuiux.cn/`).ReplaceAllString(content, "")

		// 从OSS中读取图片
		bucket := GetBucket("gameui-image2")
		body, err := bucket.GetObject(key)
		if err != nil {
			log.Println("读取图片失败", err)
			return
		}
		defer body.Close()

		// 判断图片格式是否为 gif 或 GIF
		if len(regexp.MustCompile(`\.gif$`).FindStringSubmatch(key)) > 0 {
			img.format = "gif"
			img.data, err = ioutil.ReadAll(body)
			if err != nil {
				log.Println("读取图片失败", err)
				return
			}
			return
		}

		// 将文件解码为 image.Image
		img.image, img.format, err = image.Decode(body)
		if err != nil {
			log.Println("解码图像失败", err)
			return
		}
		return
	} else {
		log.Println("直接从网络下载图片:", content)
		resp, err := http.Get(content)
		if err != nil {
			log.Println("下载图片失败", err)
			return
		}
		defer resp.Body.Close()

		// 判断图片格式是否为 gif 或 GIF
		if len(regexp.MustCompile(`\.gif$`).FindStringSubmatch(content)) > 0 {
			img.format = "gif"
			img.data, err = ioutil.ReadAll(resp.Body)
			if err != nil {
				log.Println("读取图片失败", err)
				return
			}
			println("数据长度:", len(img.data))
			return
		}

		// 将文件解码为 image.Image
		img.image, img.format, err = image.Decode(resp.Body)
		if err != nil {
			log.Println("解码图像失败", err)
			return
		}
	}
}

// 将图片输出为指定尺寸的 webp 格式(默认使用 Lanczos 缩放算法)
func (img *Image) ToWebP(width int, height int, fit string) ([]byte, error) {
	// 如果原图是GIF格式的动态图片，直接不作尺寸处理，直接转换为webp格式
	if img.format == "gif" {
		converter := giftowebp.NewConverter()
		converter.LoopCompatibility = true   // 是否兼容循环动画
		converter.WebPConfig.SetLossless(1)  // 0 有损压缩 1无损压缩
		converter.WebPConfig.SetMethod(6)    // 压缩速度 0-6 0最快 6质量最好
		converter.WebPConfig.SetQuality(100) // 压缩质量 0-100
		converter.WebPAnimEncoderOptions.SetKmin(9)
		converter.WebPAnimEncoderOptions.SetKmax(17)
		return converter.Convert(img.data)
	}
	// 如果指定了宽高却没有指定fit, 则默认fit为cover
	if width != 0 && height != 0 && fit == "" {
		fit = "cover"
	}
	// 如果未指定宽高和fit, 则不缩放图片直接返回webp
	if width == 0 && height == 0 && fit == "" {
		return webp.EncodeRGBA(img.image, 100)
	}
	switch fit {
	case "cover":
		return webp.EncodeRGBA(imaging.Fill(img.image, width, height, imaging.Center, imaging.Lanczos), 100)
	case "contain":
		return webp.EncodeRGBA(imaging.Fit(img.image, width, height, imaging.Lanczos), 100)
	case "fill":
		return webp.EncodeRGBA(imaging.Fill(img.image, width, height, imaging.Center, imaging.Lanczos), 100)
	case "inside":
		return webp.EncodeRGBA(imaging.Fit(img.image, width, height, imaging.Lanczos), 100)
	case "outside":
		return webp.EncodeRGBA(imaging.Fill(img.image, width, height, imaging.Center, imaging.Lanczos), 100)
	case "scale-down":
		return webp.EncodeRGBA(imaging.Fit(img.image, width, height, imaging.Lanczos), 100)
	default:
		return webp.EncodeRGBA(imaging.Resize(img.image, width, height, imaging.Lanczos), 100)
	}
}
