package util

import (
	"errors"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"
	"strings"

	"github.com/nfnt/resize"
)

func ResizeImage(imagePath string, width int, height int) (outputPath string, err error) {
	// 打开源图片文件
	file, err := os.Open(imagePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 解码图片
	var img image.Image
	var decodeErr error

	ext := strings.ToLower(filepath.Ext(imagePath))
	switch ext {
	case ".jpg", ".jpeg":
		img, decodeErr = jpeg.Decode(file)
	case ".png":
		img, decodeErr = png.Decode(file)
	default:
		return "", errors.New("unsupported image format")
	}

	if decodeErr != nil {
		return "", decodeErr
	}

	// 调整图片大小
	resized := resize.Resize(uint(width), uint(height), img, resize.Lanczos3)

	// 创建输出文件
	outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext
	out, err := os.Create(outputPath)
	if err != nil {
		return "", err
	}
	defer out.Close()

	// 根据文件扩展名选择编码方式
	switch ext {
	case ".jpg", ".jpeg":
		return outputPath, jpeg.Encode(out, resized, nil)
	case ".png":
		return outputPath, png.Encode(out, resized)
	default:
		return "", errors.New("unsupported image format")
	}
}

// ResizeImageByMaxWidth 按最大宽度缩放图片，保持宽高比
func ResizeImageByMaxWidth(imagePath string, maxWidth uint) (outputPath string, err error) {
	// 打开源图片文件
	file, err := os.Open(imagePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 解码图片
	var img image.Image
	var decodeErr error

	ext := strings.ToLower(filepath.Ext(imagePath))
	switch ext {
	case ".jpg", ".jpeg":
		img, decodeErr = jpeg.Decode(file)
	case ".png":
		img, decodeErr = png.Decode(file)
	default:
		return "", errors.New("unsupported image format")
	}

	if decodeErr != nil {
		return "", decodeErr
	}

	// 计算缩放后的尺寸，保持宽高比
	// 传入0作为高度，resize包会自动计算等比例的高度
	resized := resize.Resize(maxWidth, 0, img, resize.Lanczos3)

	// 创建输出文件
	outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext
	out, err := os.Create(outputPath)
	if err != nil {
		return "", err
	}
	defer out.Close()

	// 根据文件扩展名选择编码方式
	switch ext {
	case ".jpg", ".jpeg":
		return outputPath, jpeg.Encode(out, resized, nil)
	case ".png":
		return outputPath, png.Encode(out, resized)
	default:
		return "", errors.New("unsupported image format")
	}
}

// ResizeImageByMaxHeight2File 按最大高度缩放图片，保持宽高比
func ResizeImageByMaxHeight2File(imagePath string, maxHeight uint) (outputPath string, err error) {
	// 打开源图片文件
	file, err := os.Open(imagePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	// 解码图片
	var img image.Image
	var decodeErr error

	var gifImg *gif.GIF

	ext := strings.ToLower(filepath.Ext(imagePath))
	switch ext {
	case ".jpg", ".jpeg":
		img, decodeErr = jpeg.Decode(file)
	case ".png":
		img, decodeErr = png.Decode(file)
	case ".gif":
		gifImg, decodeErr = gif.DecodeAll(file)
	default:
		return "", errors.New("unsupported image format")
	}

	if decodeErr != nil {
		return "", decodeErr
	}

	// 计算缩放后的尺寸，保持宽高比
	// 传入0作为宽度，resize包会自动计算等比例的宽度
	var resized image.Image
	if gifImg == nil {
		resized = resize.Resize(0, maxHeight, img, resize.Lanczos3)
	} else {
		for i, frame := range gifImg.Image {
			resized = resize.Resize(0, maxHeight, frame, resize.Lanczos3)
			gifImg.Image[i] = resized.(*image.Paletted)
		}
	}

	// 创建输出文件
	outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext
	out, err := os.Create(outputPath)
	if err != nil {
		return "", err
	}
	defer out.Close()

	// 根据文件扩展名选择编码方式
	switch ext {
	case ".jpg", ".jpeg":
		return outputPath, jpeg.Encode(out, resized, nil)
	case ".png":
		return outputPath, png.Encode(out, resized)
	case ".gif":
		return outputPath, gif.EncodeAll(out, gifImg)
	default:
		return "", errors.New("unsupported image format")
	}
}

func ResizeImageByMaxHeight2Image(imagePath string, maxHeight uint) (output []image.Image, delay []int, err error) {
	// 打开源图片文件
	file, err := os.Open(imagePath)
	if err != nil {
		return nil, nil, err
	}
	defer file.Close()

	// 解码图片
	var img image.Image
	var decodeErr error

	var gifImg *gif.GIF

	ext := strings.ToLower(filepath.Ext(imagePath))
	switch ext {
	case ".jpg", ".jpeg":
		img, decodeErr = jpeg.Decode(file)
	case ".png":
		img, decodeErr = png.Decode(file)
	case ".gif":
		gifImg, decodeErr = gif.DecodeAll(file)
	default:
		return nil, nil, errors.New("unsupported image format")
	}

	if decodeErr != nil {
		return nil, nil, decodeErr
	}

	// 计算缩放后的尺寸，保持宽高比
	// 传入0作为宽度，resize包会自动计算等比例的宽度
	var resized []image.Image
	if gifImg == nil {
		resized = []image.Image{resize.Resize(0, maxHeight, img, resize.Lanczos3)}
	} else {
		for _, frame := range gifImg.Image {
			img := resize.Resize(0, maxHeight, frame, resize.Lanczos3)
			resized = append(resized, img)
		}
		delay = gifImg.Delay
	}
	return resized, delay, nil
}

func GetResizedIamgePathByOrgPath(orgPath string) string {
	ext := strings.ToLower(filepath.Ext(orgPath))
	return strings.TrimSuffix(orgPath, ext) + "_resized" + ext
}
