using Cinemachine;
using UnityEngine;

public class PlayerComponent : MonoBehaviour
{
    [SerializeField] private float health = 5f;

    [SerializeField] private float maxHealth = 5f;

    [SerializeField] private float stamina = 20f;

    [SerializeField] private float maxStamina = 20f;

    [SerializeField] private NoiseVisibilitySettingsManager noiseManager;
    [SerializeField] private PlayerMovementController movementController;

    [SerializeField] private PlayerAnimationController animationController;

    [HideInInspector] public FlareRegister flareRegister;

    [SerializeField] private CinemachineFreeLook cameraFreeLook;

    [SerializeField] private float knockbackDuration = 1f;

    [SerializeField] private float knockbackDistance = 5f;

    [SerializeField] private StatsOutputScreen statsOutput;

    private CinemachineBasicMultiChannelPerlin perlin;
    private float shakeTimer;

    public NoiseVisibilitySettingsManager NoiseManager => noiseManager;
    public PlayerMovementController MovementController => movementController;

    [HideInInspector] public bool IsAlive => health > 0;

    private void Awake()
    {
        flareRegister = FindObjectOfType<FlareRegister>();
    }

    // Start is called before the first frame update
    private void Start()
    {
        perlin = cameraFreeLook.GetRig(1).GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
    }

    // Update is called once per frame
    private void Update()
    {
        NoiseManager.SetRunning(MovementController.IsRunning);
        statsOutput.health = health;
        statsOutput.stamina = 20f;
        statsOutput.oxygen = 100f;

        if (shakeTimer > 0)
        {
            shakeTimer -= Time.deltaTime;

            // perlin.m_AmplitudeGain = 0;
            perlin.m_AmplitudeGain = Mathf.Lerp(perlin.m_AmplitudeGain, 0, .1f);
            if (shakeTimer <= 0f) perlin.m_AmplitudeGain = 0;
        }

        if (!IsAlive)
        {
            PlayerInteractionHandler.instance.isDead = true;
            movementController.isDead = true;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Damaging"))
        {
            print("HIT!");
            var monster = other.GetComponentInParent<MonsterComponent>();

            Damage(monster.AttackDamage, monster.ShakeCameraOnHit);
            animationController.Hit(health <= 0);
            movementController.PhysicalForceMove((transform.position - monster.transform.position) * knockbackDistance);
            movementController.LockMovement(knockbackDuration);
        }
    }


    public void ShakeCamera(float intensity, float time)
    {
        var perlin = cameraFreeLook.GetRig(1).GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>();
        perlin.m_AmplitudeGain = intensity;
        shakeTimer = time;
    }

    public void SetSensitivity(float magnitude)
    {
        movementController.SetSensitivity(magnitude);
    }

    public void Damage(float damage, bool applyShake = false)
    {
        health -= damage;
        if (applyShake) ShakeCamera(15, 5);
    }
}