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

public class MassController : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI _weightText;
    [SerializeField] private float _animationSpeed = 2f;

    private List<Rigidbody> _bodies = new List<Rigidbody>();
    private Coroutine _weightRoutine;
    private float _currentDisplayedValue = 0f;

    private enum UnitMode { Kg, G, Mg }
    private UnitMode _currentMode = UnitMode.Kg;

    private void Reset()
    {
        Collider c = GetComponent<Collider>();
        if (c != null) c.isTrigger = true;
    }

    private void Update()
    {
        if (_bodies.Count > 0) UpdateWeight();
    }

    public void AddObject(Rigidbody rb)
    {
        if (rb == null) return;
        if (!_bodies.Contains(rb))
            _bodies.Add(rb);
    }

    public void RemoveObject(Rigidbody rb)
    {
        if (rb == null) return;
        _bodies.Remove(rb);
        UpdateWeight();
    }

    public void SwitchUnit()
    {
        _currentMode = _currentMode switch
        {
            UnitMode.Kg => UnitMode.G,
            UnitMode.G => UnitMode.Mg,
            _ => UnitMode.Kg
        };
        UpdateWeight();
    }

    private void UpdateWeight()
    {
        float totalKg = 0f;
        foreach (var rb in _bodies)
        {
            if (rb == null) continue;
            LiquidContainer lc = rb.GetComponent<LiquidContainer>()
                ?? rb.GetComponentInChildren<LiquidContainer>();
            totalKg += lc != null ? lc.GetTotalMassKg() : rb.mass;
        }
        float target = ConvertValue(totalKg);
        if (_weightRoutine != null) StopCoroutine(_weightRoutine);
        _weightRoutine = StartCoroutine(AnimateWeight(target));
    }

    private float ConvertValue(float kg)
    {
        return _currentMode switch
        {
            UnitMode.G => kg * 1000f,
            UnitMode.Mg => kg * 1_000_000f,
            _ => kg
        };
    }

    private string GetUnitLabel()
    {
        return _currentMode switch
        {
            UnitMode.G => " g",
            UnitMode.Mg => " mg",
            _ => " kg"
        };
    }

    private IEnumerator AnimateWeight(float targetValue)
    {
        float elapsed = 0f;
        float startValue = _currentDisplayedValue;
        float duration = 1f / _animationSpeed;
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            _currentDisplayedValue = Mathf.Lerp(startValue, targetValue, elapsed / duration);
            _weightText.text = _currentDisplayedValue.ToString("F2") + GetUnitLabel();
            yield return null;
        }
        _currentDisplayedValue = targetValue;
        _weightText.text = targetValue.ToString("F2") + GetUnitLabel();
    }
}
