using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class AstronautController : MonoBehaviour
{
    [SerializeField] private float _moveSpeed = 3f;
    [SerializeField] private float _jumpForce = 10f;
    [SerializeField] private Planet _currentPlanet = Planet.Earth;
    [SerializeField] private AstronautAnimator _astronautAnimator;
    [SerializeField] private TextMeshProUGUI _planetText;
    [SerializeField] private TextMeshProUGUI _gravityText;
    public Planet CurrentPlanet => _currentPlanet;

    public enum Planet
    {
        Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune, Sun
    }

    private Rigidbody _rb;
    private bool _isGrounded;
    private bool _isJumping;
    private float _ratio = 1f;

    float GetGravity(Planet planet)
    {
        switch (planet)
        {
            case Planet.Mercury: return 3.72f;
            case Planet.Venus: return 8.87f;
            case Planet.Earth: return 9.81f;
            case Planet.Moon: return 1.62f;
            case Planet.Mars: return 3.721f;
            case Planet.Jupiter: return 24.79f;
            case Planet.Saturn: return 10.44f;
            case Planet.Uranus: return 8.69f;
            case Planet.Neptune: return 11.15f;
            case Planet.Sun: return 274f;
            default: return 9.81f;
        }
    }

    string GetPlanetNameUA(Planet planet)
    {
        switch (planet)
        {
            case Planet.Mercury: return "Меркурій";
            case Planet.Venus: return "Венера";
            case Planet.Earth: return "Земля";
            case Planet.Moon: return "Місяць";
            case Planet.Mars: return "Марс";
            case Planet.Jupiter: return "Юпітер";
            case Planet.Saturn: return "Сатурн";
            case Planet.Uranus: return "Уран";
            case Planet.Neptune: return "Нептун";
            case Planet.Sun: return "Сонце";
            default: return "";
        }
    }

    float GetSpeedMultiplier()
    {
        if (_currentPlanet == Planet.Moon) return 1.5f;
        return Mathf.Clamp(1f / (_ratio * 1.5f), 0.15f, 3f);
    }

    void ApplyGravity()
    {
        Physics.gravity = new Vector3(0, -GetGravity(_currentPlanet), 0);
        _ratio = GetGravity(_currentPlanet) / 9.81f;
        _astronautAnimator.SetRatio(_ratio);
        if (_planetText != null)
            _planetText.text = GetPlanetNameUA(_currentPlanet);
    }

    IEnumerator ShowGravityText()
    {
        _gravityText.text = "Прискорення падіння: " + GetGravity(_currentPlanet).ToString("F2") + " м/с²";
        float t = 0f;
        while (t < 1f)
        {
            t += Time.deltaTime * 2f;
            _gravityText.alpha = t;
            yield return null;
        }
        yield return new WaitForSeconds(4f);
        t = 1f;
        while (t > 0f)
        {
            t -= Time.deltaTime * 2f;
            _gravityText.alpha = t;
            yield return null;
        }
    }

    float GetClampedMass()
    {
        return Mathf.Clamp(_rb.mass, 30f, 100f);
    }

    void Start()
    {
        _rb = GetComponent<Rigidbody>();
        _rb.freezeRotation = true;
        if (_gravityText != null)
            _gravityText.alpha = 0f;
        ApplyGravity();
        _astronautAnimator.SetMass(GetClampedMass());
    }

    public void RefreshMass()
    {
        _astronautAnimator.SetMass(GetClampedMass());
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            _isGrounded = true;
            _isJumping = false;
        }
    }

    void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            _isGrounded = false;
        }
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1)) { _currentPlanet = Planet.Mercury; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha2)) { _currentPlanet = Planet.Venus; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha3)) { _currentPlanet = Planet.Earth; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha4)) { _currentPlanet = Planet.Moon; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha5)) { _currentPlanet = Planet.Mars; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha6)) { _currentPlanet = Planet.Jupiter; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha7)) { _currentPlanet = Planet.Saturn; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha8)) { _currentPlanet = Planet.Uranus; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha9)) { _currentPlanet = Planet.Neptune; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Alpha0)) { _currentPlanet = Planet.Sun; ApplyGravity(); }

        if (Input.GetKeyDown(KeyCode.Keypad1)) { _currentPlanet = Planet.Mercury; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad2)) { _currentPlanet = Planet.Venus; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad3)) { _currentPlanet = Planet.Earth; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad4)) { _currentPlanet = Planet.Moon; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad5)) { _currentPlanet = Planet.Mars; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad6)) { _currentPlanet = Planet.Jupiter; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad7)) { _currentPlanet = Planet.Saturn; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad8)) { _currentPlanet = Planet.Uranus; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad9)) { _currentPlanet = Planet.Neptune; ApplyGravity(); }
        if (Input.GetKeyDown(KeyCode.Keypad0)) { _currentPlanet = Planet.Sun; ApplyGravity(); }

        float currentSpeed = _moveSpeed * GetSpeedMultiplier();
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        bool isWalking = Mathf.Abs(h) > 0.1f || Mathf.Abs(v) > 0.1f;

        if (!_isJumping)
        {
            Vector3 move = new Vector3(-h, 0, -v).normalized * currentSpeed;
            _rb.velocity = new Vector3(move.x, _rb.velocity.y, move.z);
            if (isWalking)
                transform.forward = new Vector3(-h, 0, -v).normalized;
        }

        _astronautAnimator.SetWalking(isWalking && !_isJumping);

        bool canJump = _currentPlanet == Planet.Sun ? true : (_isGrounded && !_isJumping);

        if (Input.GetKeyDown(KeyCode.Space) && canJump)
        {
            _isJumping = true;
            _astronautAnimator.Jump();
            StartCoroutine(JumpForceDelay());
        }
    }

    IEnumerator JumpForceDelay()
    {
        float animSpeed = (_currentPlanet == Planet.Moon)
            ? 1.5f
            : Mathf.Clamp(1f / (_ratio * 1.5f), 0.15f, 3f);
        float delay = 0.7f / animSpeed;
        yield return new WaitForSeconds(delay);
        _rb.velocity = new Vector3(_rb.velocity.x, 0, _rb.velocity.z);
        float clampedMass = GetClampedMass();
        float savedMass = _rb.mass;
        _rb.mass = 75f;
        _rb.AddForce(Vector3.up * _jumpForce, ForceMode.Impulse);
        _rb.mass = savedMass;
        float bonus = Mathf.Lerp(1.5f, -1.5f, Mathf.InverseLerp(30f, 100f, clampedMass));
        _rb.AddForce(Vector3.up * bonus, ForceMode.VelocityChange);
        if (_gravityText != null)
            StartCoroutine(ShowGravityText());
        if (_currentPlanet == Planet.Sun)
            _isJumping = false;
    }

}
