using UnityEngine;
using UnityEngine.InputSystem;
using System.Collections;

/// <summary>
/// Modular input handler that replaces PlayerScript.
/// Handles player input routing to character systems.
/// Only active when character is player-controlled.
/// </summary>
[RequireComponent(typeof(Animator))]
public class CharacterInputHandler : MonoBehaviour
{
    [Header("References")]
    [SerializeField] private CharacterStats characterStats;
    
    // Cached components
    private Animator anim;
    private CharacterMovement characterMovement;
    private CharacterAttacks characterAttacks;
    private AnimationManager animationManager;
    private InputToAnimation inputToAnimation;
    private TeamMember teamMember;
    
    [Header("State")]
    [Tooltip("Public input vector for other scripts to read")]
    public Vector2 input;
    
    [Tooltip("Is the character currently blocking")]
    public bool block;
    
    [Tooltip("Is the character currently dodging")]
    public bool dodge;
    
    [Tooltip("Are attacks enabled (permission flag)")]
    public bool attackEnabled = true;
    
    [Tooltip("Is the character in a helpless state")]
    public bool helpless;
    
    [Tooltip("Is the character being held")]
    public bool held;
    
    [Header("Camera")]
    [SerializeField] private Camera mainCamera;
    
    [Header("Block/Dodge Settings")]
    [SerializeField] private float blockDuration = 0.5f;
    [SerializeField] private float dodgeDuration = 0.4f;

    #region Unity Lifecycle
    
    private void Awake()
    {
        CacheComponents();
    }
    
    private void Start()
    {
        // Initialize camera if not set
        if (mainCamera == null)
        {
            mainCamera = Camera.main;
        }
        
        // Initialize state
        block = false;
        dodge = false;
        helpless = false;
        held = false;
    }
    
    private void OnEnable()
    {
        // When enabled (player takes control), ensure input starts fresh
        input = Vector2.zero;
    }
    
    private void OnDisable()
    {
        // When disabled (AI takes control), clear input
        input = Vector2.zero;
        block = false;
        dodge = false;
    }
    
    private void CacheComponents()
    {
        anim = GetComponent<Animator>();
        characterMovement = GetComponent<CharacterMovement>();
        characterAttacks = GetComponent<CharacterAttacks>();
        animationManager = GetComponent<AnimationManager>();
        inputToAnimation = GetComponent<InputToAnimation>();
        teamMember = GetComponent<TeamMember>();
    }
    
    #endregion
    
    #region Input System Callbacks
    
    /// <summary>
    /// Called by Input System for movement input (joystick/WASD)
    /// </summary>
    public void OnMove(InputAction.CallbackContext context)
    {
        if (!enabled) return;
        
        input = context.ReadValue<Vector2>();
    }
    
    /// <summary>
    /// Mobile-specific movement handler
    /// </summary>
    public void OnMoveMobile()
    {
        if (!enabled) return;
        
        // Block camera updates only during blocking or dodging
        if (block || dodge) return;
        
        // Input is already filled by OnMove from the Input System
        // Handle any mobile-specific camera logic here if needed
    }
    
    /// <summary>
    /// Called by Input System for jump input
    /// </summary>
    public void OnJump(InputAction.CallbackContext context)
    {
        if (!enabled || !context.performed) return;
        if (helpless || held) return;
        
        // Note: Jump is handled by CharacterMovement's gravity/grounding system
        // This callback can be used for additional jump logic if needed
    }
    
    /// <summary>
    /// Handle punch/jab attacks - routed through InputToAnimation
    /// </summary>
    public void OnPunch(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    public void OnKick(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    public void OnJab(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    public void OnHaymaker(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    // Mobile attack handlers
    public void OnPunchMobileNew(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    public void OnKickMobileNew(InputAction.CallbackContext context)
    {
        // No-op: Handled by InputToAnimation
    }
    
    /// <summary>
    /// Toggle pause menu
    /// </summary>
    public void OnTogglePause(InputAction.CallbackContext context)
    {
        if (!context.performed) return;
        
        PlayerManagerNew playerManager = FindFirstObjectByType<PlayerManagerNew>();
        if (playerManager != null)
        {
            // Toggle pause based on current state
            if (playerManager.pause)
            {
                playerManager.Resume();
            }
            else
            {
                playerManager.Pause();
            }
        }
    }
    
    #endregion
    
    #region Block and Dodge
    
    public void StartBlock()
    {
        if (block || dodge || helpless || held) return;
        
        StartCoroutine(BlockCoroutine());
    }
    
    public void StartDodge()
    {
        if (block || dodge || helpless || held) return;
        
        StartCoroutine(DodgeCoroutine());
    }
    
    private IEnumerator BlockCoroutine()
    {
        block = true;
        
        if (anim != null)
        {
            anim.SetBool("Block", true);
        }
        
        yield return new WaitForSeconds(blockDuration);
        
        block = false;
        
        if (anim != null)
        {
            anim.SetBool("Block", false);
        }
    }
    
    private IEnumerator DodgeCoroutine()
    {
        dodge = true;
        
        if (anim != null)
        {
            anim.SetTrigger("Dodge");
        }
        
        yield return new WaitForSeconds(dodgeDuration);
        
        dodge = false;
    }
    
    #endregion
    
    #region Public Methods
    
    /// <summary>
    /// Set player input active/inactive
    /// </summary>
    public void SetPlayerInputActive(bool active)
    {
        PlayerInput playerInput = GetComponent<PlayerInput>();
        if (playerInput != null)
        {
            playerInput.enabled = active;
        }
    }
    
    /// <summary>
    /// Get the current input direction relative to camera
    /// </summary>
    public Vector3 GetDirectionRelativeToCamera()
    {
        if (mainCamera == null) return Vector3.zero;
        
        Vector3 cameraForward = mainCamera.transform.forward;
        Vector3 cameraRight = mainCamera.transform.right;
        
        cameraForward.y = 0;
        cameraRight.y = 0;
        cameraForward.Normalize();
        cameraRight.Normalize();
        
        return (cameraForward * input.y + cameraRight * input.x).normalized;
    }
    
    /// <summary>
    /// Update the camera reference
    /// </summary>
    public void SetMainCamera(Camera camera)
    {
        mainCamera = camera;
        
        // Also update CharacterMovement if present
        if (characterMovement != null)
        {
            // CharacterMovement has its own mainCamera field
        }
    }
    
    #endregion
    
    #region Legacy Compatibility (No-ops for Input System routing)
    
    // These methods exist for legacy compatibility with PlayerScript
    // All attack inputs are now routed through InputToAnimation
    
    public void OnSpinningBackfist(InputAction.CallbackContext c) { }
    public void OnElbowSmash(InputAction.CallbackContext c) { }
    public void OnChargePunch(InputAction.CallbackContext c) { }
    public void OnAirPunch(InputAction.CallbackContext c) { }
    public void OnDropKick(InputAction.CallbackContext c) { }
    public void OnLowKick(InputAction.CallbackContext c) { }
    public void OnStrike(InputAction.CallbackContext c) { }
    public void OnLook(InputAction.CallbackContext c) { }
    public void OnSprint(InputAction.CallbackContext c) { }
    
    // Vicious attacks
    public void OnChokeslam(InputAction.CallbackContext c) { }
    public void OnSuplex(InputAction.CallbackContext c) { }
    public void OnGiantSwing(InputAction.CallbackContext c) { }
    public void OnDiamondCrusher(InputAction.CallbackContext c) { }
    
    // Special attacks
    public void OnRKO(InputAction.CallbackContext c) { }
    public void OnSpear(InputAction.CallbackContext c) { }
    public void OnRockBottom(InputAction.CallbackContext c) { }
    public void OnSumoSlap(InputAction.CallbackContext c) { }
    public void OnJavelinTackle(InputAction.CallbackContext c) { }
    public void OnF5(InputAction.CallbackContext c) { }
    public void OnSwantomBomb(InputAction.CallbackContext c) { }
    
    // Mobile vicious/special
    public void OnViciousAttackMobile(InputAction.CallbackContext c) { }
    public void OnSpecialAttackMobile(InputAction.CallbackContext c) { }
    
    // Punch variations
    public void OnRight(InputAction.CallbackContext c) { }
    public void OnLeftHook(InputAction.CallbackContext c) { }
    public void OnRightHook(InputAction.CallbackContext c) { }
    public void OnLeftElbow(InputAction.CallbackContext c) { }
    public void OnRightElbow(InputAction.CallbackContext c) { }
    public void OnRightBody(InputAction.CallbackContext c) { }
    public void OnPowerPunchLeft(InputAction.CallbackContext c) { }
    public void OnSupermanPunch(InputAction.CallbackContext c) { }
    
    // Kick variations
    public void OnLegKickRight(InputAction.CallbackContext c) { }
    public void OnBodyKickRight(InputAction.CallbackContext c) { }
    public void OnKneeRight(InputAction.CallbackContext c) { }
    public void OnBackSideKick(InputAction.CallbackContext c) { }
    public void OnFrontKickRight(InputAction.CallbackContext c) { }
    public void OnLegPowerKickRight(InputAction.CallbackContext c) { }
    
    // Jump variations
    public void OnJumpBack(InputAction.CallbackContext c) { }
    public void OnJumpLeft(InputAction.CallbackContext c) { }
    public void OnJumpRight(InputAction.CallbackContext c) { }
    
    // Block variations
    public void OnBlockStepBack(InputAction.CallbackContext c) { }
    public void OnBlockBodyLeft(InputAction.CallbackContext c) { }
    public void OnBlockLeg(InputAction.CallbackContext c) { }
    
    #endregion
}
