package images

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/h2non/bimg"
)

type ProcessOptions struct {
	Width   int
	Height  int
	Quality int
	Format  string // webp, avif, png, jpg, jpeg
	Cover   bool
}

func ProcessImage(buffer []byte, opts ProcessOptions) ([]byte, error) {
	startTime := time.Now()
	img := bimg.NewImage(buffer)

	origSize, _ := img.Size()
	origType := img.Type()
	origKB := len(buffer) / 1024

	options := bimg.Options{
		Width:   opts.Width,
		Height:  opts.Height,
		Quality: opts.Quality,
	}

	if opts.Quality == 0 {
		options.Quality = 85
	}

	// Cover mode: Enlarge and crop to fill the dimensions
	if opts.Cover {
		options.Crop = true
		options.Enlarge = true
	}

	format := strings.ToLower(opts.Format)
	switch format {
	case "webp":
		options.Type = bimg.WEBP
	case "avif":
		options.Type = bimg.AVIF
	case "png":
		options.Type = bimg.PNG
	case "jpg", "jpeg":
		options.Type = bimg.JPEG
	}

	log.Printf("[IMAGE-PROCESS-START] Original: %dx%d (%s, %dKB). Target -> W:%d, H:%d, Q:%d, Format:%v, Cover:%v",
		origSize.Width, origSize.Height, origType, origKB,
		options.Width, options.Height, options.Quality, options.Type, opts.Cover)

	newImage, err := img.Process(options)
	if err != nil {
		log.Printf("[IMAGE-PROCESS-ERROR] Failed after %v: %v", time.Since(startTime), err)
		return nil, fmt.Errorf("failed to process image: %w", err)
	}

	newKB := len(newImage) / 1024
	diff := origKB - newKB

	log.Printf("[IMAGE-PROCESS-DONE] Success in %v! New Size: %dKB (Difference: %dKB)", time.Since(startTime), newKB, diff)

	return newImage, nil
}
