package browser

import (
	"fmt"
	"math/rand"
	"time"
)

// CdpClickXYHuman hace click en las coordenadas absolutas (x, y) de la página con
// comportamiento humano: mueve el ratón hasta el punto por una trayectoria de
// Bézier cúbica (CdpMoveMouseHuman) y despacha mousePressed/mouseReleased con una
// micro-pausa variable (30-90 ms) entre ambos.
//
// Es el PRIMITIVO de click compartido por las tres vías de acción del agente:
//   - por selector CSS  → CdpClickHuman (obtiene el bbox y llama aquí).
//   - por #ref del AX tree → CdpClickRef (resuelve backendDOMNodeId → bbox → aquí).
//   - por visión → click sobre el bounding box que devuelve OCR/YOLO.
// Construir un único primitivo evita tener tres caminos de click divergentes.
func CdpClickXYHuman(c *CDPConn, x, y float64, opts MouseHumanOpts) error {
	if c == nil {
		return fmt.Errorf("cdp click xy human: conexion nula")
	}

	// Mover el ratón hasta el destino con trayectoria humana.
	if err := CdpMoveMouseHuman(c, x, y, opts); err != nil {
		return fmt.Errorf("cdp click xy human: mover raton: %w", err)
	}

	clickParams := map[string]any{
		"type":       "mousePressed",
		"x":          x,
		"y":          y,
		"button":     "left",
		"clickCount": 1,
	}
	if _, err := c.sendCDP("Input.dispatchMouseEvent", clickParams); err != nil {
		return fmt.Errorf("cdp click xy human: mousePressed: %w", err)
	}

	// Pausa entre press y release según el modo de velocidad.
	if pms := clickPauseMs(opts.Mode); pms > 0 {
		time.Sleep(time.Duration(pms) * time.Millisecond)
	}

	clickParams["type"] = "mouseReleased"
	if _, err := c.sendCDP("Input.dispatchMouseEvent", clickParams); err != nil {
		return fmt.Errorf("cdp click xy human: mouseReleased: %w", err)
	}

	return nil
}

// clickPauseMs devuelve la pausa (ms) entre press y release según el modo de
// velocidad: human 30-90, auto/fast 5-15, instant 0.
func clickPauseMs(mode string) int {
	switch mode {
	case "instant":
		return 0
	case "fast", "auto":
		return 5 + rand.Intn(11) // 5..15
	default: // "human" o ""
		return 30 + rand.Intn(61) // 30..90
	}
}
