using System;
using System.Collections;
using System.Collections.Generic;
using ScriptableObjectArchitecture;
using UnityEngine;
using UnityEngine.InputSystem;

public class Knob : MonoBehaviour
{
    [field: SerializeField] public int CurrentStep { get; private set; } = 1;

    [SerializeField] private InputActionAsset _playerControls = default;
    [SerializeField] private GameObject _buttonArt = default;

    [Header("Settings")]
    [SerializeField] private float _startingPosition = 0;
    [SerializeField] private float _minPosition = 0;
    [SerializeField] private float _maxPosition = 360;
    [SerializeField] private int _steps = 1;

    // [Header("Assets")] [SerializeField] private BoolVariable _knobLock = default;
    [SerializeField] private IntVariable _knobStep = default;
    [SerializeField] private GameEvent _knobStateUpdateEvent = default;
    [SerializeField] private GameEvent _selectableUpdateEvent = default;

    [Header("Refs")]
    [SerializeField] private Selectable _selectable = default;
    [SerializeField] private AudioSource _playOnTurn = default;

    private InputAction turnKnobAction;

    private void OnEnable()
    {
        _selectableUpdateEvent.AddListener(HandleSelectableChange);
    }

    private void OnDisable()
    {
        _selectableUpdateEvent.RemoveListener(HandleSelectableChange);
    }

    void Start()
    {
        var currentAngles = _buttonArt.transform.localEulerAngles;
        var newAngle = new Vector3(currentAngles.x, currentAngles.y, Mathf.Clamp(_startingPosition, _minPosition, _maxPosition));
        _buttonArt.transform.localEulerAngles = newAngle;
    }

    private void HandleSelectableChange()
    {
        if (_selectable.Selected)
        {
            SetupInputListeners();
        }
        else
        {
            RemoveInputListeners();
        }
    }

    private void SetupInputListeners()
    {
        var playerControlsActionMap = _playerControls.FindActionMap("Player");
        turnKnobAction = playerControlsActionMap.FindAction("TurnKnob");

        turnKnobAction.performed += TurnKnob;
    }

    private void RemoveInputListeners()
    {
        var playerControlsActionMap = _playerControls.FindActionMap("Player");
        turnKnobAction = playerControlsActionMap.FindAction("TurnKnob");

        turnKnobAction.performed -= TurnKnob;
    }

    private void TurnKnob(InputAction.CallbackContext context)
    {
        int turnDirection = context.ReadValue<float>() > 0 ? 1 : -1;

        if ((CurrentStep == 1 && turnDirection == -1) || (CurrentStep == _steps && turnDirection == 1))
        {
            // do nothing
        }
        else
        {
            UpdateKnobState(turnDirection);
            UpdateKnobRotation(turnDirection);
        }
    }

    private void UpdateKnobState(int direction)
    {
        CurrentStep += direction;
        _knobStep.Value = CurrentStep;
        _knobStateUpdateEvent.Raise();
        _playOnTurn.Play();
    }

    private void UpdateKnobRotation(int direction)
    {
        float degreesPerTurn = (_maxPosition - _minPosition) / (_steps - 1);
        var currentAngles = _buttonArt.transform.localEulerAngles;
        var newAngle = new Vector3(currentAngles.x, currentAngles.y, currentAngles.z + (degreesPerTurn * direction));
        _buttonArt.transform.localEulerAngles = newAngle;
    }
}
