// Game state detection for D2R.
package d2r

import (
	"image"

	"git.cloonar.com/openclawd/iso-bot/pkg/plugin"
	"git.cloonar.com/openclawd/iso-bot/pkg/engine/vision"
)

// Detector implements plugin.GameDetector for D2R.
type Detector struct {
	config   Config
	services plugin.EngineServices
	vision   *vision.Pipeline
}

// NewDetector creates a D2R state detector.
func NewDetector(config Config, services plugin.EngineServices) *Detector {
	return &Detector{
		config:   config,
		services: services,
		vision:   vision.NewPipeline(0.8), // 80% confidence threshold
	}
}

// DetectState analyzes a screenshot and returns the current game state.
func (d *Detector) DetectState(frame image.Image) plugin.GameState {
	// Priority-based detection:
	// 1. Check for in-game first (health orb visible)
	// 2. Check for loading screen (but only if not in-game)
	// 3. Check for main menu
	// 4. Check for character select
	// 5. Check for death screen

	if d.isInGame(frame) {
		vitals := d.ReadVitals(frame)
		if vitals.HealthPct <= 0.01 { // Consider very low health as dead
			return plugin.StateDead
		}
		return plugin.StateInGame
	}
	if d.isLoading(frame) {
		return plugin.StateLoading
	}
	if d.isMainMenu(frame) {
		return plugin.StateMainMenu
	}
	if d.isCharacterSelect(frame) {
		return plugin.StateCharacterSelect
	}
	return plugin.StateUnknown
}

// ReadVitals reads health and mana from the orbs.
func (d *Detector) ReadVitals(frame image.Image) plugin.VitalStats {
	healthRegion := d.services.Region("health_orb")
	manaRegion := d.services.Region("mana_orb")
	
	var healthPct, manaPct float64
	
	// Read health percentage from red-filled pixels in health orb
	if !healthRegion.Empty() {
		healthColor := vision.ColorRange{
			LowerH: d.config.Colors.HealthFilled.LowerH,
			UpperH: d.config.Colors.HealthFilled.UpperH,
			LowerS: d.config.Colors.HealthFilled.LowerS,
			UpperS: d.config.Colors.HealthFilled.UpperS,
			LowerV: d.config.Colors.HealthFilled.LowerV,
			UpperV: d.config.Colors.HealthFilled.UpperV,
		}
		healthPct = d.vision.ReadOrbPercentage(frame, healthRegion, healthColor)
	}
	
	// Read mana percentage from blue-filled pixels in mana orb
	if !manaRegion.Empty() {
		manaColor := vision.ColorRange{
			LowerH: d.config.Colors.ManaFilled.LowerH,
			UpperH: d.config.Colors.ManaFilled.UpperH,
			LowerS: d.config.Colors.ManaFilled.LowerS,
			UpperS: d.config.Colors.ManaFilled.UpperS,
			LowerV: d.config.Colors.ManaFilled.LowerV,
			UpperV: d.config.Colors.ManaFilled.UpperV,
		}
		manaPct = d.vision.ReadOrbPercentage(frame, manaRegion, manaColor)
	}
	
	return plugin.VitalStats{
		HealthPct: healthPct,
		ManaPct:   manaPct,
		XPPct:     0.0, // TODO: Implement XP bar reading
	}
}

// IsInGame returns true if health orb is visible.
func (d *Detector) IsInGame(frame image.Image) bool {
	return d.isInGame(frame)
}

func (d *Detector) isLoading(frame image.Image) bool {
	// Check for loading screen by looking for mostly black screen (>90%)
	// AND ensuring no health orb colors are present in the health orb region
	bounds := frame.Bounds()
	totalPixels := 0
	darkPixels := 0

	// Sample every 10 pixels for performance
	step := 10
	for y := bounds.Min.Y; y < bounds.Max.Y; y += step {
		for x := bounds.Min.X; x < bounds.Max.X; x += step {
			c := frame.At(x, y)
			r, g, b, _ := c.RGBA()
			// Convert to 8-bit
			r, g, b = r>>8, g>>8, b>>8

			totalPixels++
			// Consider pixel dark if all channels are below 30
			if r < 30 && g < 30 && b < 30 {
				darkPixels++
			}
		}
	}

	if totalPixels == 0 {
		return false
	}

	// Require more than 90% dark screen
	darkPercentage := float64(darkPixels) / float64(totalPixels)
	if darkPercentage <= 0.9 {
		return false
	}

	// Additional check: ensure no health colors in health orb region
	healthRegion := d.services.Region("health_orb")
	if !healthRegion.Empty() {
		healthColor := vision.ColorRange{
			LowerH: d.config.Colors.HealthFilled.LowerH,
			UpperH: d.config.Colors.HealthFilled.UpperH,
			LowerS: d.config.Colors.HealthFilled.LowerS,
			UpperS: d.config.Colors.HealthFilled.UpperS,
			LowerV: d.config.Colors.HealthFilled.LowerV,
			UpperV: d.config.Colors.HealthFilled.UpperV,
		}
		// If health colors are detected in health orb region, it's not loading
		if d.vision.HasColorInRegion(frame, healthRegion, healthColor) {
			return false
		}
	}

	return true
}

func (d *Detector) isMainMenu(frame image.Image) bool {
	// TODO: Template match main menu elements or check for specific colors/text
	// For now, this is a placeholder
	return false
}

func (d *Detector) isCharacterSelect(frame image.Image) bool {
	// TODO: Template match character select screen
	// For now, this is a placeholder
	return false
}

func (d *Detector) isInGame(frame image.Image) bool {
	// Check if health orb region contains red pixels indicating health
	healthRegion := d.services.Region("health_orb")
	if healthRegion.Empty() {
		return false
	}
	
	healthColor := vision.ColorRange{
		LowerH: d.config.Colors.HealthFilled.LowerH,
		UpperH: d.config.Colors.HealthFilled.UpperH,
		LowerS: d.config.Colors.HealthFilled.LowerS,
		UpperS: d.config.Colors.HealthFilled.UpperS,
		LowerV: d.config.Colors.HealthFilled.LowerV,
		UpperV: d.config.Colors.HealthFilled.UpperV,
	}
	
	return d.vision.HasColorInRegion(frame, healthRegion, healthColor)
}
