using Godot;
using System;
using System.Collections.Generic;
using RustyOptions;

namespace Movementtests.systems;


public partial class WallHugSystem : Node3D
{
    [Signal]
    public delegate void WallDetectedEventHandler();
    
    private List<RayCast3D> _raycasts;
    public Option<Vector3> WallHugLocation { get; private set; } = Option<Vector3>.None;
    public Option<Vector3> WallHugNormal { get; private set; } = Option<Vector3>.None;
    
    public void Init()
    {
        _raycasts = new List<RayCast3D>();
        _raycasts.Add(GetNode<RayCast3D>("front"));
        _raycasts.Add(GetNode<RayCast3D>("front2"));
        _raycasts.Add(GetNode<RayCast3D>("back"));
        _raycasts.Add(GetNode<RayCast3D>("back2"));
        _raycasts.Add(GetNode<RayCast3D>("left"));
        _raycasts.Add(GetNode<RayCast3D>("left2"));
        _raycasts.Add(GetNode<RayCast3D>("right"));
        _raycasts.Add(GetNode<RayCast3D>("right2"));
    }

    public override void _PhysicsProcess(double delta)
    {
        base._PhysicsProcess(delta);
        CheckWallHugging();
        if (IsWallHugging())
            EmitSignal(SignalName.WallDetected);
    }

    public void CheckWallHugging()
    {
        foreach (RayCast3D raycast in _raycasts)
        {
            if (raycast.IsColliding())
            {
                WallHugLocation = raycast.GetCollisionPoint().Some();
                WallHugNormal = raycast.GetCollisionNormal().Some();
                return;
            }
        }
        WallHugLocation = Option<Vector3>.None;
        WallHugNormal = Option<Vector3>.None;
    }

    public bool IsWallHugging()
    {
        return !WallHugLocation.IsNone;
    }
}
