using Intrepid.Utilities;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;

namespace Intrepid.Core.UI
{
    public class NewsTickerUI : MonoBehaviour
    {
        [GroupConfigurations, SerializeField] private TextMeshProUGUI textMesh;
        [GroupConfigurations, SerializeField] private float speed = 50f;
        [GroupConfigurations, SerializeField] private float timeToTick = 3f;
        [GroupConfigurations, SerializeField] private float adjustment = 2f;
        [GroupConfigurations, SerializeField, ToggleLeft] private bool operateWhenStart;

        private RectTransform RectTransform { get; set; }
        private float Direction { get; set; }
        [GroupDebug, ShowInInspector, ReadOnly, DisplayAsString] private Timer Timer { get; } = new();
        public string Text { get; set; }
        private float TimeToTick { get; set; }

        public TextMeshProUGUI TextMesh => textMesh;

        private void Awake()
        {
            RectTransform = GetComponent<RectTransform>();
            Direction = -1;
            TimeToTick = timeToTick;
            Text = textMesh.text;
        }

        private void OnEnable()
        {
            if (operateWhenStart) Operational();
        }

        public void Update()
        {
            if (Timer.IsNotRunning) return;
            
            if (string.IsNullOrEmpty(textMesh.text)) return;
            var size = textMesh.rectTransform.rect.width - RectTransform.rect.width;
            if (size <= 0) return;
            
            Timer.Update(Time.deltaTime);
            if (!Timer.Check(TimeToTick)) return;
            
            var realSpeed = Direction > 0 ? 4f * speed : -speed;
            textMesh.rectTransform.anchoredPosition += new Vector2(realSpeed * Time.deltaTime, 0);
            if (Direction < 0 && textMesh.rectTransform.anchoredPosition.x <= -(size + adjustment))
            {
                Direction = 1f;
                TimeToTick = timeToTick / 3f;
                textMesh.rectTransform.anchoredPosition = new Vector2(-(size + adjustment), 0);
                Timer.Restart();
            }
            else if (textMesh.rectTransform.anchoredPosition.x >= 0)
            {
                Direction = -1f;
                TimeToTick = timeToTick;
                textMesh.rectTransform.anchoredPosition = Vector2.zero;
                Timer.Restart();
            }
        }

        public void Operational(string text = null, bool forceReset = false)
        {
            textMesh.text = string.IsNullOrWhiteSpace(text) ? Text : text;
            if (Timer.IsRunning && !forceReset) return;
            textMesh.rectTransform.anchoredPosition = Vector2.zero;
            Timer.Start();
        }

        public void NotOperational(string text = null)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                Text = text;
                textMesh.text = Text;
            }
            Timer.Stop();
        }
    }
}