package game

import (
	"fmt"
	"log"
	"runtime/debug"

	rl "github.com/gen2brain/raylib-go/raylib"
)

// SafeExecute runs a function and recovers from panics
func SafeExecute(action func() error) (err error) {
	defer func() {
		if r := recover(); r != nil {
			stack := debug.Stack()
			log.Printf("Recovered from panic: %v\nStack trace:\n%s", r, stack)
			err = fmt.Errorf("recovered from panic: %v", r)
		}
	}()
	return action()
}

// SafeExecuteVoid runs a void function and recovers from panics
func SafeExecuteVoid(action func()) {
	defer func() {
		if r := recover(); r != nil {
			stack := debug.Stack()
			log.Printf("Recovered from panic: %v\nStack trace:\n%s", r, stack)
		}
	}()
	action()
}

func RayIntersectsBox(ray rl.Ray, boxMin, boxMax rl.Vector3) bool {
	tmin := (boxMin.X - ray.Position.X) / ray.Direction.X
	tmax := (boxMax.X - ray.Position.X) / ray.Direction.X

	if tmin > tmax {
		tmin, tmax = tmax, tmin
	}

	tymin := (boxMin.Z - ray.Position.Z) / ray.Direction.Z
	tymax := (boxMax.Z - ray.Position.Z) / ray.Direction.Z

	if tymin > tymax {
		tymin, tymax = tymax, tymin
	}

	if (tmin > tymax) || (tymin > tmax) {
		return false
	}

	if tymin > tmin {
		tmin = tymin
	}
	if tymax < tmax {
		tmax = tymax
	}

	tzmin := (boxMin.Y - ray.Position.Y) / ray.Direction.Y
	tzmax := (boxMax.Y - ray.Position.Y) / ray.Direction.Y

	if tzmin > tzmax {
		tzmin, tzmax = tzmax, tzmin
	}

	if (tmin > tzmax) || (tzmin > tmax) {
		return false
	}

	return true
}
