using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace Minesweeper.Presentation.Views
{
    [Serializable]
    public sealed class MenuSliderView
    {
        [SerializeField] private Slider slider;
        [SerializeField] private TMP_Text minText;
        [SerializeField] private TMP_Text maxText;
        [SerializeField] private TMP_Text valueText;
        [SerializeField] private string valueLabel;

        public event Action<int> ValueChanged;

        public int Value => slider != null ? Mathf.RoundToInt(slider.value) : 0;

        public void Bind(Slider slider, TMP_Text minText, TMP_Text maxText, TMP_Text valueText)
        {
            RemoveListeners();
            this.slider = slider;
            this.minText = minText;
            this.maxText = maxText;
            this.valueText = valueText;
            AddListeners();
        }

        public void AddListeners()
        {
            if (slider != null)
            {
                slider.onValueChanged.AddListener(OnValueChanged);
            }
        }

        public void RemoveListeners()
        {
            if (slider != null)
            {
                slider.onValueChanged.RemoveListener(OnValueChanged);
            }
        }

        public void Configure(int min, int max, int value, string label)
        {
            if (slider == null)
            {
                return;
            }

            valueLabel = label;
            var clampedMax = Mathf.Max(min, max);
            var clampedValue = Mathf.Clamp(value, min, clampedMax);
            slider.wholeNumbers = true;
            slider.minValue = min;
            slider.maxValue = clampedMax;
            slider.SetValueWithoutNotify(clampedValue);
            SetText(minText, min);
            SetText(maxText, clampedMax);
            SetValueText(clampedValue);
        }

        private void OnValueChanged(float value)
        {
            var intValue = Mathf.RoundToInt(value);
            SetValueText(intValue);
            ValueChanged?.Invoke(intValue);
        }

        private void SetValueText(int value)
        {
            if (valueText != null)
            {
                valueText.text = string.IsNullOrEmpty(valueLabel) ? value.ToString() : $"{valueLabel}: {value}";
            }
        }

        private static void SetText(TMP_Text text, int value)
        {
            if (text != null)
            {
                text.text = value.ToString();
            }
        }
    }
}
