package ai

import (
	"bytes"
	"fmt"
	"image"
	"image/jpeg"
)

// EncodeScreenshot converts raw RGBA pixel data to a JPEG image.
// If the source dimensions exceed maxWidth x maxHeight, the image is
// downscaled using nearest-neighbor sampling (fast, no external deps).
// Returns the JPEG bytes.
func EncodeScreenshot(rgba []byte, srcWidth, srcHeight, maxWidth, maxHeight, quality int) ([]byte, error) {
	expectedLen := srcWidth * srcHeight * 4
	if len(rgba) < expectedLen {
		return nil, fmt.Errorf("RGBA buffer too small: got %d bytes, expected %d for %dx%d", len(rgba), expectedLen, srcWidth, srcHeight)
	}

	if quality <= 0 || quality > 100 {
		quality = 75
	}

	// Create source image from RGBA buffer
	src := image.NewRGBA(image.Rect(0, 0, srcWidth, srcHeight))
	copy(src.Pix, rgba[:expectedLen])

	// Determine output dimensions
	dstWidth, dstHeight := srcWidth, srcHeight
	if srcWidth > maxWidth || srcHeight > maxHeight {
		dstWidth, dstHeight = fitDimensions(srcWidth, srcHeight, maxWidth, maxHeight)
	}

	var img image.Image = src

	// Downscale if needed using nearest-neighbor sampling
	if dstWidth != srcWidth || dstHeight != srcHeight {
		dst := image.NewRGBA(image.Rect(0, 0, dstWidth, dstHeight))
		for y := 0; y < dstHeight; y++ {
			srcY := y * srcHeight / dstHeight
			for x := 0; x < dstWidth; x++ {
				srcX := x * srcWidth / dstWidth
				srcIdx := (srcY*srcWidth + srcX) * 4
				dstIdx := (y*dstWidth + x) * 4
				dst.Pix[dstIdx+0] = src.Pix[srcIdx+0] // R
				dst.Pix[dstIdx+1] = src.Pix[srcIdx+1] // G
				dst.Pix[dstIdx+2] = src.Pix[srcIdx+2] // B
				dst.Pix[dstIdx+3] = src.Pix[srcIdx+3] // A
			}
		}
		img = dst
	}

	// Encode to JPEG
	var buf bytes.Buffer
	if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: quality}); err != nil {
		return nil, fmt.Errorf("encode JPEG: %w", err)
	}

	return buf.Bytes(), nil
}

// fitDimensions calculates the largest dimensions that fit within max bounds
// while preserving aspect ratio.
func fitDimensions(srcW, srcH, maxW, maxH int) (int, int) {
	ratio := float64(srcW) / float64(srcH)
	w, h := maxW, int(float64(maxW)/ratio)
	if h > maxH {
		h = maxH
		w = int(float64(maxH) * ratio)
	}
	if w <= 0 {
		w = 1
	}
	if h <= 0 {
		h = 1
	}
	return w, h
}
