using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Unity.Cinemachine;
using Unity.VisualScripting;
using UnityEditor.Experimental.GraphView;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.InputSystem;
using static Unity.Cinemachine.CinemachineSplineDolly;
using static UnityEngine.Rendering.DebugUI;

public class PlayerCharacterController : MonoBehaviour
{
    private CharacterController _cController;
    private Animator _anim;

    private PlayerStateMachine _stateMachine;

    //환경
    private float _gravityValue = Physics.gravity.y; //중력

    //이동
    private Vector2 _moveInput; // 입력받은 이동 방향
    private Vector3 _velocityY = new Vector3(0,-2f,0); // 플레이어Y의 속도 //Y축만 물리법칙의 지배를 일부 받기 때문에 필요
    private Vector3 _moveTargetDir; // 실제 가고자하는 이동방향
    private float _moveCutTimer = 0f; //이동금지 타이머
    private Vector3 _rootMotionVelocity; //루트모션 사용시

    //캐릭터 스피드
    [SerializeField] private float _spdCoefficient = 4f; //스피드 계수
    [SerializeField] private float _acceleration = 4f;   // 가속도
    [SerializeField] private float _deceleration = 20f;  // 감속도
    private float _walkSpdRatio = 0.3f; // 걷기 속도 블렌드 비율 //여기를 수정하면 에디터의 블렌드도 수정해야함
    private float _runSpdRatio = 1f; // 달리기 속도 블렌드 비율 //여기를 수정하면 에디터의 블렌드도 수정해야함
    private float _currentSpd; //현재 스피드

    //점프
    [SerializeField] private float _jumpPower = 3.0f; //점프 힘
    private float _jumpReadyCool = 0.8f; //점프 쿨타임
    private float _jumpReadyCoolTimer = 0f; //점프 쿨타이머
    private int _jumpCount = 0;
    private int _maxJumpCount = 2;

    //대쉬
    [SerializeField] private AnimationCurve _dodgeCurve; // 변속용 커브
    [SerializeField] private float _dodgeDistance = 5f;  // 총 대쉬 거리
    [SerializeField] private float _dodgeDuration = 0.5f; // 대쉬 지속 시간
    private float _dodgeTimer = 0f;                       // 대쉬 진행 측정용
    private float _inertiaTimer = 0f;                     // 관성 타이머
    private float _inertiaTime = 0f;
    private Vector3 _dodgeDir;                            // 대쉬 시작 시점의 방향 고정

    //카메라 전환
    private CancellationTokenSource _cameraDelayChangeCts; //지연전환 취소 토큰
    public enum PlayerRotationMode {CameraCoupled, CameraDecoupled}
    public PlayerRotationMode RotationMode = PlayerRotationMode.CameraCoupled;

    //조준모드용 세팅
    [Header("AimMode Rotation Settings")]
    private Vector2 _lookInput;
    private float _lookPitch = 0f;
    [SerializeField] private float _lookSensitivity = 0.1f;
    [SerializeField] private float _upperLookLimit = 80f;  // 위로 보기 제한
    [SerializeField] private float _lowerLookLimit = -80f; // 아래로 보기 제한


    //게걸음 이동
    public bool Strafe = false;
    public void SetStrafeMode(bool b) => Strafe = b;

    //조준모드
    public bool IsAiming => _stateMachine != null && _stateMachine.IsAiming;

    //캐릭터 관련
    public CharacterIdentity PlayerCharacterIdentity { get; set; }
    public PlayerStat PlayerCharacterStat{ get; set; }
    private Renderer[] _renderers;

    //상호작용
    public SphereCollider InteractionCollider;
    public List<IInteractable> InteractionTargets = new List<IInteractable>();
    public IInteractable InteractionOnTarget = null;
    private bool _actionExitRequested = false;

    //무기
    //[SerializeField] private Weapon _weapon;

    /*
     *  웨폰 모듈로 따로 빼볼것
     * 
    //차지공격
    //private float _chargePowerAdded = 0f; //차지 기본값에 더해줄 힘 //weapon 모듈로 뺄것
    //private float _chargePowerFirst = 20f; //차지 기본값 (바로 시전해도 값이 있어야 되기 때문) //weapon 모듈로 뺄것
    //private float _chargePowerDelta = 0.2f; //차지할때 힘이 더해질 단위시간 //weapon 모듈로 뺄것
    private event Action _chargeAttackCallback; //차지공격시 실행될 함수

    //private AimingModule _aimingModule; //이건 weapon 모듈로 빼볼것

    //private float _bowShootCoolTime = 0.5f; // weapon(Bow)로 뺄것 
    //private float _bowShootCoolTimer = 0f; // weapon(Bow)로 뺄것 

    //[SerializeField] private LineRenderer _arrowTraceRenderer; // weapon(Bow)로 뺄것
    //private int _arrowTraceResolution = 30; // 화살 궤적 선을 구성하는 점의 개수 (정밀도) // weapon(Bow)로 뺄것
    //private float _arrowTraceStepTime = 0.1f; // 화살 궤적 점 사이의 시간 간격 // weapon(Bow)로 뺄것
    */

    private void Awake()
    {
        _cController = GetComponent<CharacterController>();
        _anim = GetComponent<Animator>();
        _stateMachine = GetComponent<PlayerStateMachine>();
        PlayerCharacterIdentity = GetComponent<CharacterIdentity>();
        PlayerCharacterStat = GetComponent<PlayerStat>();

        _renderers = GetComponentsInChildren<Renderer>();
    }

    private void Start()
    {
        _stateMachine.SetMaxJumpCount(_maxJumpCount);
        SetCursorLockState(true);
    }

    public void PlayerStart()
    {
        Debug.Log("플레이 시작!!");
    }

    private void Update()
    {
        //캐릭터 컨트롤러는 FixedUpdate보다 Update에서 하는게 권장됨
        CheckGround();

        StateUpdate();

        Movement();
        WorkGravity();
        ApplyMove();

        CheckInteraction();

        TickTimer();
        //PlayerDebug();
    }

    private void FixedUpdate()
    {

    }

    private void PlayerDebug()
    {
        Debug.Log($"isGrounded : {_stateMachine.IsGrounded}");
    }

    #region 상태 업데이트
    private void StateUpdate()
    {
        if (_stateMachine.CurrentState == PlayerState.Trans) return;
        if (_stateMachine.CurrentState == PlayerState.Action)
        {
            // Action 중 탈출 입력 감지
            if (_moveInput.sqrMagnitude > Mathf.Epsilon || _actionExitRequested)
            {
                EndAction();
                _actionExitRequested = false;
            }
            return;
        }

        if (_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer > 0f)
            return; // 관성상태면 상태변환 안함
        else if(_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer <= 0f)
        {
            _inertiaTime = 0f;

            if (_moveInput.sqrMagnitude < Mathf.Epsilon )
            {
                _stateMachine.ChangeState(PlayerState.Idle);
                _currentSpd = 0f;
            }
            else
            {
                _stateMachine.ChangeState(_stateMachine.IsRunInputPressed ? PlayerState.Run : PlayerState.Walk);
                _currentSpd = _walkSpdRatio * _spdCoefficient;
            }
        }

        if (_stateMachine.CurrentState == PlayerState.Dodge) return;

        // 땅에서 추락할때
        if (!_stateMachine.IsGrounded && _velocityY.y < 0f && _stateMachine.CurrentState != PlayerState.Attack && _stateMachine.CurrentState != PlayerState.Charge)
        {
            _stateMachine.ChangeState(PlayerState.Fall);
        }
        //점프에서 바닥에 닿을때
        else if (_stateMachine.IsGrounded && _stateMachine.CurrentState == PlayerState.Fall)
        {
            _stateMachine.ChangeState(PlayerState.Idle);
            _moveCutTimer = 0.1f;
        }

        if (_moveInput.sqrMagnitude < Mathf.Epsilon && _stateMachine.CanMove() && _stateMachine.CurrentState != PlayerState.Attack) // 지상 이동이 가능하고 공격중도 아닌데 이동입력이 없는상태 - 거의 0
        {
            _stateMachine.ChangeState(PlayerState.Idle);
        }
        else if(_stateMachine.CanMove() && _stateMachine.CurrentState != PlayerState.Attack) //지상이동이 가능하고 공격중이 아닌데 이동입력이 있다
        {
            // 런키를 누른 상태면 뛰는 상태, 아니면 걷는 상태
            _stateMachine.ChangeState(_stateMachine.IsRunInputPressed ? PlayerState.Run : PlayerState.Walk);
        }

        if (_moveCutTimer > 0)
            _stateMachine.IsMoveCut = true;
        else
            _stateMachine.IsMoveCut = false;

        if (_jumpReadyCoolTimer > 0)
            _stateMachine.IsJumpCool = true;
        else
            _stateMachine.IsJumpCool = false;


        if(_stateMachine.IsGrounded)
        {
            _jumpCount = 0;
        }
    }
    #endregion

    #region 체크
    private bool IsCloseToGround(float checkDistance)
    {
        return Physics.Raycast(transform.position, Vector3.down, checkDistance);
    }
    private void CheckGround()
    {
        _stateMachine.IsGrounded = _cController.isGrounded;
        _stateMachine.IsCloseToGround = IsCloseToGround(0.9f);

        _anim.SetBool("IsGrounded", _stateMachine.IsGrounded);
        _anim.SetBool("IsCloseToGround", _stateMachine.IsCloseToGround);
    }
    #endregion

    #region 중력
    private void WorkGravity()
    {
        if (_stateMachine.IsGrounded && _velocityY.y < 0)
        {
            _velocityY.y = -2f;
        }

        _velocityY.y += _gravityValue * Time.deltaTime;
        _anim.SetFloat("velocityY", _velocityY.y);
    }
    #endregion

    #region 이동
    private void Movement()
    {
        if (_stateMachine.CurrentState == PlayerState.Action) return;
        if (_stateMachine.CurrentState == PlayerState.Trans) return;
        if (_stateMachine.CurrentState == PlayerState.Inertia) return;

        //구르기중일때 전용 로직
        if (_stateMachine.CurrentState == PlayerState.Dodge)
        {
            float normalizedTime = (_dodgeDuration - _dodgeTimer) / _dodgeDuration; // 0 ~ 1 사이의 진행률

            if (normalizedTime >= 1f)
            {
                // 구르기 종료 -> 관성 로직
                _stateMachine.ChangeState(PlayerState.Inertia);
                _moveTargetDir = _moveTargetDir * 0.3f;
                _inertiaTimer = _inertiaTime;
                return;
            }

            // 커브에서 현재 시점의 '속도 배율'을 가져옴
            // 그래프의 전체 넓이는 1
            _anim.GetInteger("DodgeAnimType");
            float curveValue = _dodgeCurve.Evaluate(normalizedTime);

            // 최종 속도 = (전체 거리 / 시간) * 커브 배율 ??
            _currentSpd = (_dodgeDistance / _dodgeDuration) * curveValue;
            _moveTargetDir = _dodgeDir * _currentSpd;

            // 구르기 중엔 즉시 회전 (선택 사항)
            //transform.rotation = Quaternion.LookRotation(_dodgeDir);

            return;
        }

        float targetSpd = 0;

        if(_moveInput.sqrMagnitude > Mathf.Epsilon) //입력이 있다
        {
            targetSpd = _stateMachine.IsRunInputPressed ? _runSpdRatio * _spdCoefficient : _walkSpdRatio * _spdCoefficient;
        }

        // _currentSpd가 targetSpd로 서서히 접근
        float accelWeight = _stateMachine.CurrentState == PlayerState.Run ? 2 : 1;  //런일때 가속도 가중치
        float currentStepSpeed = (targetSpd > _currentSpd) ? _acceleration : _deceleration; 
        _currentSpd = Mathf.MoveTowards(_currentSpd, targetSpd, currentStepSpeed * accelWeight * Time.deltaTime);

        _anim.SetFloat("speedRatio", _currentSpd / _spdCoefficient);
        
        Vector3 camForward = Camera.main.transform.forward; //메인카메라의 로컬기준 앞쪽방향
        camForward.y = 0; //높이를 무시하기 위해 0으로
        camForward.Normalize();

        Vector3 camRight = Camera.main.transform.right; //메인카메라의 로컬기준 x축, 오른쪽 방향
        camRight.y = 0; //높이를 무시하기 위해 0으로
        camRight.Normalize();

        Vector3 moveDir = new Vector3(_moveInput.x, 0, _moveInput.y);

        _moveTargetDir = (moveDir.x * camRight + moveDir.z * camForward) * _currentSpd;//오른쪽을 눌렀다면 camRight 방향으로 그만큼, 위쪽을 눌렀다면 camForward방향으로 그만큼 가라

        //방향키 방향으로 회전하며 이동
        //RotationByMove();

        //모드별 회전
        RotationByMode();
        _anim.SetFloat("DirectX", moveDir.x * _currentSpd / _spdCoefficient);
        _anim.SetFloat("DirectY", moveDir.z * _currentSpd / _spdCoefficient);

    }
    private void RotationByMove()
    {
        if(_moveTargetDir.magnitude > Mathf.Epsilon)
        {
            Quaternion lookTarget = Quaternion.LookRotation(_moveTargetDir); // 방향 벡터를 쿼터니언 회전값으로 전환
            transform.rotation = Quaternion.Slerp(transform.rotation, lookTarget, Time.deltaTime * 10);
        }
    }
    private void RotationByMode()
    {
        if (IsAiming) //조준 모드일때는 마우스가 캐릭터 자체를 회전시키고 카메라가 따라간다 (Third Person Follow)
        {
            // 좌우 회전 (Yaw): 캐릭터 본체를 직접 회전시킴
            float yaw = _lookInput.x * _lookSensitivity;
            transform.Rotate(Vector3.up * yaw);

            // 상하 회전 (Pitch): 캐릭터는 그대로 두고 내부 변수만 계산
            _lookPitch -= _lookInput.y * _lookSensitivity;
            _lookPitch = Mathf.Clamp(_lookPitch, _lowerLookLimit, _upperLookLimit);

           CinemachineCamera liveCm = GameManager.Instance.Camera.GetLiveCinemachineCamera();

            if(liveCm != null)
            {
                Transform lookTarget = liveCm.LookAt;
                lookTarget.localRotation = Quaternion.Euler(_lookPitch, 0, 0);
            }
        }
        else //조준 모드가 아니면 회전모드를 따라간다
        {
            switch (RotationMode)
            {
                case PlayerRotationMode.CameraCoupled:
                    {
                        SetStrafeMode(true);
                        RecenterPlayer();
                        break;
                    }
                case PlayerRotationMode.CameraDecoupled:
                    {
                        SetStrafeMode(false);
                        break;
                    }
            }
        }
    }

    public void RecenterPlayer(float damping = 0)
    {
        if (transform == null)
            return;

        Vector3 cameraForward = Camera.main.transform.forward;
        cameraForward.y = 0;
        cameraForward.Normalize();

        Quaternion targetRotation = Quaternion.LookRotation(cameraForward);

        transform.rotation = Quaternion.Slerp(transform.rotation,targetRotation,damping > 0 ? Time.deltaTime / damping : 1f );
    }

    #endregion

    #region 속도적용
    private void OnAnimatorMove()
    {
        if(_stateMachine.CurrentState == PlayerState.Dodge)
        {
            _rootMotionVelocity = _anim.deltaPosition / Time.deltaTime;
        }

        if (_stateMachine.CurrentState == PlayerState.Action || _stateMachine.CurrentState == PlayerState.Trans)
        {
            _cController.Move(_anim.deltaPosition);
            transform.rotation *= _anim.deltaRotation;
        }
    }
    private void ApplyMove()
    {
        //지상에서 지상이동이 가능한 상황이 아니고, 공중에서 공중이동도 가능한 상황이 아니라면, 또한 대쉬중도 아니라면, 관성 상태도 아니라면
        if (!_stateMachine.CanMove() && !_stateMachine.CanControlInAir() && _stateMachine.CurrentState != PlayerState.Dodge && _stateMachine.CurrentState != PlayerState.Inertia)
        {
            _moveTargetDir.x = 0f;
            _moveTargetDir.z = 0f;
        }

        Vector3 finalVector = new Vector3(_moveTargetDir.x, _velocityY.y, _moveTargetDir.z);
        
        _cController.Move(finalVector * Time.deltaTime); // xz 이동벡터를 적용
    }


    #endregion

    #region 점프
    private void JumpAction()
    {
        _velocityY.y = Mathf.Sqrt(_jumpPower * -2f * _gravityValue);
    }
    #endregion

    #region 앉기
    public void PointSitAction(Transform trn)
    {
        _moveInput = Vector2.zero;
        _moveTargetDir = Vector3.zero;
        _currentSpd = 0f;
        _actionExitRequested = false;

        _anim.SetFloat("speedRatio", 0f);
        _anim.SetFloat("DirectX", 0f);
        _anim.SetFloat("DirectY", 0f);

        _cController.enabled = false;

        transform.position = trn.position;
        transform.rotation = trn.rotation;

        _cController.enabled = true;

        _anim.SetBool("IsSit",true);

        RotationMode = PlayerRotationMode.CameraDecoupled;

        float freezeTime = 3f;

        _stateMachine.ChangeState(PlayerState.Trans);

        _moveCutTimer = freezeTime;
         // 앉기 진입 애니메이션 길이에 맞게 조정
        _ = Util.RunDelayed(freezeTime, () => {
            _stateMachine.ChangeState(PlayerState.Action);
        }, default);
    }
    #endregion

    #region 액션 종료
    public void EndAction()
    {
        if (_stateMachine.CurrentState != PlayerState.Action) return;

        _anim.SetBool("IsSit", false);
        float freezeTime = 2f;

        _stateMachine.ChangeState(PlayerState.Trans);

        _moveCutTimer = freezeTime;
        _ = Util.RunDelayed(freezeTime, () => {
            _stateMachine.ChangeState(PlayerState.Idle);
            RotationMode = PlayerRotationMode.CameraCoupled;
            InteractionOnTarget.InteractEnd(this);
            InteractionOnTarget = null;
        }, default);
    }
    #endregion

    #region 타미어
    private void TickTimer()
    {
        if (_jumpReadyCoolTimer > 0) _jumpReadyCoolTimer -= Time.deltaTime; if (_jumpReadyCoolTimer < 0) _jumpReadyCoolTimer = 0f;
        if (_moveCutTimer > 0) _moveCutTimer -= Time.deltaTime; if (_moveCutTimer < 0) _moveCutTimer = 0f;
        if(_dodgeTimer > 0) _dodgeTimer -= Time.deltaTime; ; if (_dodgeTimer < 0) _dodgeTimer = 0f;
        if (_inertiaTimer > 0) _inertiaTimer -= Time.deltaTime;if (_inertiaTimer < 0) _inertiaTimer = 0f;
    }
    #endregion

    #region 입력
    public void MoveInput(Vector2 moveInput)
    {
        _moveInput = moveInput;
    }
    public void SprintInput(InputState inputState)
    {
        if (inputState == InputState.Performing)
        {
            _stateMachine.IsRunInputPressed = true;
        }
        else if (inputState == InputState.Canceled)
        {
            _stateMachine.IsRunInputPressed = false;
        }
    }
    public void JumpInput(InputState inputState)
    {
        if (ActionExitCheck()) return;
        if (_stateMachine.CanJump())
        {
            if (inputState == InputState.Started)
            {
                _anim.SetTrigger("jumpTrigger");
                _stateMachine.ChangeState(PlayerState.Jump);
                _jumpReadyCoolTimer = _jumpReadyCool;
                _ = Util.RunDelayed(0.1f, JumpAction, default);

                _jumpCount++;
                _stateMachine.RecordJump();
                   
            }
        }
    }
    public void DodgeInput(InputState inputState)
    {
        // 구르기 가능한 상태일 때만
        if (inputState == InputState.Started && _stateMachine.CanDodge())
        {
            Vector3 camForward = Camera.main.transform.forward;
            camForward.y = 0;
            camForward.Normalize();

            // 입력이 없으면 카메라가 보는 앞방향, 있으면 입력 방향
            _dodgeDir = _moveInput.sqrMagnitude > Mathf.Epsilon ? _moveTargetDir.normalized : camForward;


            float angle = Vector3.SignedAngle(camForward, _dodgeDir, Vector3.up);
            int dodgeAnimType = 0;
            if (angle < 0) angle += 360f; // -180 +180 ==> 0~360

            if ((angle >= 0f && angle < 22.5f) || (angle >= 337.5f && angle <= 360f))
            {
                dodgeAnimType = 0; //상 : Fwd 애니메이션
            }
            else if(angle >= 22.5f && angle < 67.5f)
            {
                dodgeAnimType = 1;  //우상 : Fwd 애니메이션
            }
            else if(angle >= 67.5f && angle < 112.5f)
            {
                dodgeAnimType = 2; //우 : Right 애니메이션
            }
            else if (angle >= 112.5f && angle < 157.5f)
            {
                dodgeAnimType = 3; //우하 : Right 애니메이션
            }
            else if(angle >= 157.5f && angle < 202.5f)
            {
                dodgeAnimType = 4; //하 : Back 애니메이션
            }
            else if (angle >= 202.5f && angle < 247.5f)
            {
                dodgeAnimType = 5; //좌하 : Left 애니메이션
            }
            else if(angle >= 247.5f && angle < 292.5f)
            {
                dodgeAnimType = 6; //좌 : Left 애니메이션
            }
            else if(angle >= 292.5f && angle < 337.5f)
            {
                dodgeAnimType = 7; //좌상 : Fwd 애니메이션
            }

            _inertiaTime = 0.5f;

            //각도 따라 다른 애니메이션 재생
            _anim.SetInteger("DodgeAnimType", dodgeAnimType);
            _anim.SetTrigger("DodgeTrigger");

            // 상태 전환 및 타이머 초기화
            _stateMachine.ChangeState(PlayerState.Dodge);
            _dodgeTimer = _dodgeDuration;
        }
    }
    public void AimToggleInput(InputState inputState)
    {
        if (inputState == InputState.Started)
        {
            if (_stateMachine.IsAiming)
            {
                _stateMachine.IsAiming = false;
                GameManager.Instance.InGameUI.VisibleCrossHair(false);
            }
            else
            {
                _stateMachine.IsAiming = true;
                GameManager.Instance.InGameUI.VisibleCrossHair(true);
            }
        }
    }

    public void InteractInput()
    {
        if (ActionExitCheck()) return;
        if (_stateMachine.CurrentState == PlayerState.Trans) return;

        if (InteractionTargets.Count > 0)
        {
            InteractionOnTarget.InteractExec(this); // 실제 상호작용 실행
        }
    }

    public void LookInput(Vector2 lookInput)
    {
        _lookInput = lookInput;
    }
    #endregion

    #region 기타 효과
    public void HideCharacter(int flag)
    {
        if (flag == 0)
        {
            foreach(Renderer rd in _renderers)
            {
                foreach(Material m in rd.materials)
                {
                    if(m.HasProperty("_DissolvePower"))
                        m.SetFloat("_DissolvePower", 0);
                }
            }
        }
        else if (flag == 1)
        {

            foreach (Renderer rd in _renderers)
            {
                foreach (Material m in rd.materials)
                {
                    if (m.HasProperty("_DissolvePower"))
                        m.SetFloat("_DissolvePower", 1);
                }
            }
        }
    }
    public void HideCharacterTrueDelay(float delay)
    {
        _ = Util.RunDelayed(delay, ()=>HideCharacter(1), default);
    }
    #endregion

    #region 헬퍼
    public void SetCursorLockState(bool isLocked)
    {
        Cursor.lockState = isLocked ? CursorLockMode.Locked : CursorLockMode.None;
        Cursor.visible = !isLocked;
    }
    #endregion

    private bool ActionExitCheck()
    {
        if (_stateMachine.CurrentState == PlayerState.Action)
            _actionExitRequested = true;

        return _actionExitRequested;
    }

    private void CheckInteraction()
    {
        if(InteractionTargets.Count > 0)
        {
            
            for(int i=0; i < InteractionTargets.Count;i++)
            {
                if(i == 0)
                {
                    InteractionOnTarget = InteractionTargets[i];
                    InteractionOnTarget.InteractOpen();
                }
                else
                    InteractionTargets[i].InteractClose();

            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        // 상호작용 객체인지 확인
        if (other.TryGetComponent<IInteractable>(out IInteractable interactable))
        {
            if (InteractionTargets.Contains(interactable)) return;
            InteractionTargets.Add(interactable);
        }
    }

    private void OnTriggerExit(Collider other)
    {
        // 상호작용 객체인지 확인
        if (other.TryGetComponent<IInteractable>(out IInteractable interactable))
        {
            interactable.InteractClose();
            InteractionTargets.Remove(interactable);
        }
    }
}
