﻿using UnityEngine;

/// <summary>
/// Applique un effet de headbob (tremblement de caméra) pour imiter la marche.
/// À placer sur le même GameObject que PlayerMotor.
///
/// SETUP :
///   Aucun — se branche automatiquement sur la Camera enfant et PlayerMotor.
///   Tous les paramètres sont réglables dans l'Inspector.
/// </summary>
[RequireComponent(typeof(PlayerMotor))]
public class CameraHeadbob : MonoBehaviour
{
    // ── Références ────────────────────────────────────────────────────────────
    private PlayerMotor _motor;
    private Transform _cameraTransform;

    // ── Position de repos de la caméra ────────────────────────────────────────
    private Vector3 _cameraRestPosition;

    // ── Timer interne ─────────────────────────────────────────────────────────
    private float _bobTimer;

    // ─────────────────────────────────────────────────────────────────────────
    // Paramètres Inspector
    // ─────────────────────────────────────────────────────────────────────────

    [Header("Headbob")]
    [Tooltip("Fréquence du bob (cycles par seconde) — ~1.8 pour une marche naturelle")]
    public float bobFrequency = 1.8f;

    [Tooltip("Amplitude verticale (haut/bas) en unités Unity")]
    public float bobAmplitudeY = 0.05f;

    [Tooltip("Amplitude horizontale (gauche/droite) — moitié du vertical est naturel")]
    public float bobAmplitudeX = 0.025f;

    [Tooltip("Vitesse de retour à la position de repos quand le joueur est immobile")]
    public float bobReturnSpeed = 6f;

    // ─────────────────────────────────────────────────────────────────────────
    // Init
    // ─────────────────────────────────────────────────────────────────────────

    private void Awake()
    {
        _motor = GetComponent<PlayerMotor>();
    }

    private void Start()
    {
        Camera cam = GetComponentInChildren<Camera>();
        if (cam == null)
        {
            Debug.LogError("[CameraHeadbob] Aucune Camera trouvée en enfant du joueur !");
            enabled = false;
            return;
        }

        _cameraTransform = cam.transform;
        _cameraRestPosition = _cameraTransform.localPosition;
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Update
    // ─────────────────────────────────────────────────────────────────────────

    private void Update()
    {
        bool isMoving = _motor.IsMoving;
        bool isGrounded = _motor.IsGrounded;

        if (isMoving && isGrounded)
        {
            ApplyBob();
        }
        else
        {
            ReturnToRest();
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Privé
    // ─────────────────────────────────────────────────────────────────────────

    private void ApplyBob()
    {
        // Avance le timer en fonction de la vitesse de marche
        _bobTimer += Time.deltaTime * bobFrequency * (2f * Mathf.PI);

        // Sinusoïde verticale — complète un cycle haut/bas par pas
        float bobY = Mathf.Sin(_bobTimer) * bobAmplitudeY;

        // Sinusoïde horizontale — deux fois plus rapide (un pas gauche + un pas droit
        // pour chaque montée/descente verticale)
        float bobX = Mathf.Cos(_bobTimer * 2f) * bobAmplitudeX;

        Vector3 targetPos = _cameraRestPosition + new Vector3(bobX, bobY, 0f);
        _cameraTransform.localPosition = Vector3.Lerp(
            _cameraTransform.localPosition,
            targetPos,
            Time.deltaTime * bobFrequency * 10f
        );
    }

    private void ReturnToRest()
    {
        // Réinitialise le timer progressivement pour éviter un saut brutal
        // quand le joueur se remet à marcher
        _bobTimer = Mathf.Lerp(_bobTimer, 0f, Time.deltaTime * bobReturnSpeed);

        _cameraTransform.localPosition = Vector3.Lerp(
            _cameraTransform.localPosition,
            _cameraRestPosition,
            Time.deltaTime * bobReturnSpeed
        );
    }
}