package agent

import (
	"bytes"
	"fmt"
	"image"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"

	"github.com/disintegration/imaging"
)

// Image sanitization constants (moved from telegram/image_sanitize.go).
const (
	// imageMaxSide is the maximum pixels per side before resize.
	imageMaxSide = 1200
	// imageSanitizeMaxBytes is the max file size after compression (5MB, Anthropic API limit).
	imageSanitizeMaxBytes = 5 * 1024 * 1024
)

// jpegQualities is the grid of quality levels to try during sanitization.
var jpegQualities = []int{85, 75, 65, 55, 45, 35}

// Ensure standard image decoders are registered.
func init() {
	image.RegisterFormat("jpeg", "\xff\xd8", jpeg.Decode, jpeg.DecodeConfig)
	image.RegisterFormat("png", "\x89PNG", png.Decode, png.DecodeConfig)
}

// SanitizeImage resizes and compresses an image for LLM vision input.
// Applied uniformly to all channels at the agent loop level.
// Pipeline: decode → auto-orient EXIF → resize if >1200px → JPEG compress until <5MB.
func SanitizeImage(inputPath string) (string, error) {
	img, err := imaging.Open(inputPath, imaging.AutoOrientation(true))
	if err != nil {
		return "", fmt.Errorf("open image: %w", err)
	}

	bounds := img.Bounds()
	w, h := bounds.Dx(), bounds.Dy()

	if w > imageMaxSide || h > imageMaxSide {
		img = imaging.Fit(img, imageMaxSide, imageMaxSide, imaging.Lanczos)
	}

	for _, quality := range jpegQualities {
		var buf bytes.Buffer
		if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: quality}); err != nil {
			return "", fmt.Errorf("encode jpeg (q=%d): %w", quality, err)
		}
		if buf.Len() <= imageSanitizeMaxBytes {
			outPath := filepath.Join(os.TempDir(), fmt.Sprintf("goclaw_sanitized_%d.jpg", os.Getpid()))
			if err := os.WriteFile(outPath, buf.Bytes(), 0644); err != nil {
				return "", fmt.Errorf("write sanitized image: %w", err)
			}
			return outPath, nil
		}
	}

	return "", fmt.Errorf("image too large even at lowest quality (dimensions: %dx%d)", w, h)
}
