package producer

import (
	"image"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	log "github.com/sirupsen/logrus"

	"gocv.io/x/gocv"
)

const (
	GDALPansharpenCommand = "gdal_pansharpen.py {{.PANGTiff}} {{.MSSGTiff}} {{.FUSGTiff}} -r cubic -of GTiff"
)

// IHS 变换是一种将 RGB 空间转换为亮度、色调和饱和度的变换方法
func PansharpenIHS(panImage, mssImage gocv.Mat) gocv.Mat {
	log.Println("start pansharpen IHS")
	mss32F := gocv.NewMat()
	mssImage.ConvertTo(&mss32F, gocv.MatTypeCV32FC4)

	// 调整 MSS 图像的大小到与 PAN 图像相同的大小
	log.Println("resize mss to pan size")
	mssResized := gocv.NewMat()
	defer mssResized.Close()
	gocv.Resize(mss32F, &mssResized,
		image.Point{X: panImage.Cols(), Y: panImage.Rows()}, 0, 0, gocv.InterpolationCubic)

	// 将 MSS 图像从 BGR 转换为 HLS
	mssHLS := gocv.NewMat()
	defer mssHLS.Close()
	gocv.CvtColor(mssResized, &mssHLS, gocv.ColorBGRToHLS)

	// 分离 HLS 通道 只有3个通道
	// Hue
	// Lightness
	// Saturation
	hlsChannels := gocv.Split(mssHLS)

	// 使用 PAN 图像替换亮度分量（Intensity）
	// hlsChannels[1] = pan32

	// 将 PAN 图像转换为与 HLS 亮度分量相同的范围
	panFloat := gocv.NewMat()
	defer panFloat.Close()
	panImage.ConvertTo(&panFloat, gocv.MatTypeCV32F)
	log.Println("normalize pan to 0-255")
	gocv.Normalize(panFloat, &panFloat, 0, 255, gocv.NormMinMax)

	hlsFloat := gocv.NewMat()
	defer hlsFloat.Close()
	hlsChannels[1].ConvertTo(&hlsFloat, gocv.MatTypeCV32F)
	gocv.Normalize(hlsFloat, &hlsFloat, 0, 255, gocv.NormMinMax)

	// 替换亮度分量
	hlsChannels[1] = panFloat

	// 合并通道
	gocv.Merge(hlsChannels, &mssHLS)

	// 将图像从 HLS 转换回 BGR
	fusedImage := gocv.NewMat()
	defer fusedImage.Close()
	log.Println("cvt color from HLS to BGR")
	gocv.CvtColor(mssHLS, &fusedImage, gocv.ColorHLSToBGR)

	// 交换 B 和 R 通道
	channels := gocv.Split(fusedImage)
	defer channels[0].Close() // B
	defer channels[1].Close() // G
	defer channels[2].Close() // R

	// 交换 B 和 R 通道
	swappedChannels := []gocv.Mat{channels[2], channels[1], channels[0]}
	gocv.Merge(swappedChannels, &fusedImage)

	fused16U := gocv.NewMat()
	fusedImage.ConvertTo(&fused16U, gocv.MatTypeCV16UC3)

	return fused16U
}

func GDALPansharpen(panTiff, mssTiff, fusedTiff string) error {
	os.MkdirAll(filepath.Dir(fusedTiff), 0755)
	// pansharpenCmd := exec.Command("gdal_pansharpen.py", "-w 0.6 -w 0.1 -w 0.3 -w 0 -b 3 -b 2 -b 1", panTiff, mssTiff, fusedTIff, "-r cubic", "-of GTiff")
	pansharpenCmd := exec.Command("gdal_pansharpen.py",
		"-w", "0.4", "-w", "0.2", "-w", "0.4", "-w", "0",
		"-b", "3", "-b", "2", "-b", "1",
		"-r", "cubic", "-of", "GTiff",
		panTiff,
		mssTiff,
		fusedTiff)
	log.Println("Run Command: ", pansharpenCmd.String())
	pansharpenCmd.Stdout = os.Stdout
	pansharpenCmd.Stderr = os.Stderr
	return pansharpenCmd.Run()
}

func GDALTranslate(srcTiff, dstJPG string) error {
	if dstJPG == "" {
		dstJPG = strings.TrimSuffix(srcTiff, ".tiff") + ".jpg"
	}
	// gdal_translate -of JPEG -outsize 50% 50% -r bilinear input.tif output.jpg
	cmd := exec.Command("gdal_translate", "-of", "JPEG",
		srcTiff, dstJPG)
	log.Println("Run Command: ", cmd.String())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}
