using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using Ktyl.Util;

[RequireComponent(typeof(PlayerInput))]
public class PlayerInputHandler : MonoBehaviour
{
    //to get the artifact id you are near to
    [SerializeField] private SerialInt _nearbyArtefactID;

    [SerializeField]
    private PlayerInputSettings _inputSettings;

    [SerializeField]
    private Camera _camera;

    [SerializeField] private DialogueSystem _dialogue;

    public class PlayerInputState
    {
        public BufferedInput Jump;
        public BufferedInput Blink;
        public BufferedInput Use;
        public BufferedInput Freeze;
        public CameraRelativeInput Move;
        public Vector2 Look;
        public float MoveRotation;

        public PlayerInputState( float jumpBuffer, float blinkBuffer, float useBuffer , float freezeBuffer)
        {
            Jump = new BufferedInput( jumpBuffer );
            Blink = new BufferedInput( blinkBuffer );
            Use  = new BufferedInput( useBuffer );
            Freeze = new BufferedInput( freezeBuffer );
            Move = new CameraRelativeInput();
            Look = Vector2.zero;
        }

        public void Update( float deltaTime )
        {
            Jump.Update(deltaTime);
            Blink.Update(deltaTime);
            Use.Update(deltaTime);
            Freeze.Update(deltaTime);
        }
    }

    public PlayerInputState InputState => _state;

    private PlayerInputState _state;

    private void Awake()
    {
        _state = new PlayerInputState(
            _inputSettings.JumpBufferTime,
            _inputSettings.BlinkBufferTime,
            _inputSettings.UseBufferTime,
            _inputSettings.FreezeBufferTime
        ) ;
        
        // run a first time update to ensure the dialogue system has an updated
        // value for the player's input control scheme
        _dialogue.UpdateControlPrompts(GetComponent<PlayerInput>());
    }

    private void FixedUpdate()
    {
        _state.Update( Time.fixedDeltaTime);
        
        float cameraRotation = _camera.transform.rotation.eulerAngles.y;
        _state.Move.SetAngle(-cameraRotation);
    }

    public void SetCameraRotation(float angle)
        => _state.Move.SetAngle(angle);

    public void Look(InputAction.CallbackContext context)
        => _state.Look = context.ReadValue<Vector2>();

    public void Move(InputAction.CallbackContext context)
        => _state.Move.SetValue(context.ReadValue<Vector2>());

    public void Blink( InputAction.CallbackContext context )
        => _state.Blink.Set( context.ReadValueAsButton() );

    public void Jump( InputAction.CallbackContext context )
        => _state.Jump.Set( context.ReadValueAsButton() );

    public void Use(InputAction.CallbackContext context)
    {
         _state.Use.Set( context.ReadValueAsButton() );   
         
        if(context.started)
            EventHandler.current.ArtefactPickUp(_nearbyArtefactID.Value);
    }

    public void Freeze(InputAction.CallbackContext context)
    {
        _state.Freeze.Set( context.ReadValueAsButton() );

    }
}