using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Sirenix.Utilities;
using UnityEngine;
using UnityEngine.UIElements;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Wearable;
using VOID.UserInterface.Game.Util;

namespace VOID.UserInterface.Game.Tooltip
{
    public class WearableTooltipUI : ITooltip
    {
        // VisualElement - Container
        private readonly VisualElement _templateElement;
        
        // VisualElements - Sections
        private readonly VisualElement _titleSection;
        private readonly VisualElement _detailsSection;
        private readonly VisualElement _descriptionSection;
        private readonly VisualElement _footSection;
        
        // VisualElements - Data
        private readonly SlotUI _wearableIcon = new();
        private readonly List<DetailsElement> _details = new();
        private readonly Label _wearableName;
        private readonly Label _wearableQuality;
        private readonly Label _wearableType;
        private readonly Label _wearableDescription;
        private readonly Label _wearableValue;
        private readonly Label _wearableWeight;

        public WearableTooltipUI(VisualElement templateElement)
        {
            // Tooltip for this type
            _templateElement = templateElement.Q(null, "tooltip");
            
            // Sections
            _titleSection = templateElement.Q("title-section");
            _detailsSection = templateElement.Q("details-section");
            _descriptionSection = templateElement.Q("description-section");
            _footSection = templateElement.Q("foot-section");
            
            // Elements
            _wearableIcon.Init(templateElement.Q("wearable-icon"), SlotType.None, -1);
            _wearableName = templateElement.Q<Label>("wearable-name");
            _wearableQuality = templateElement.Q<Label>("wearable-quality");
            _wearableType = templateElement.Q<Label>("wearable-type");
            _wearableDescription = templateElement.Q<Label>("wearable-description");
            _wearableValue = templateElement.Q<Label>("wearable-value");
            _wearableWeight = templateElement.Q<Label>("wearable-weight");
        }

        public void Show(WearableObject wearable)
        {
            _wearableIcon.Set(wearable);
            _templateElement.style.display = DisplayStyle.Flex;
            
            FillBasicInfo(wearable);
            FillDetails(wearable);
        }

        public void Hide()
        {
            _templateElement.style.display = DisplayStyle.None;
        }

        public Vector2 GetSize()
        {
            return new Vector2(_templateElement.worldBound.width, _templateElement.worldBound.height);
        }

        private void FillBasicInfo(WearableObject wearable)
        {
            _wearableName.text = wearable.basicData.finalName;
            _wearableQuality.text = wearable.itemData.quality.displayName;
            _wearableType.text = wearable.GetType().Name;
            _wearableDescription.text = wearable.basicData.description;
            _descriptionSection.style.display = _wearableDescription.text.IsNullOrWhitespace() ? DisplayStyle.None : DisplayStyle.Flex;
            _wearableValue.text = wearable.itemData.finalValue.ToString(CultureInfo.InvariantCulture);
            _wearableWeight.text = wearable.itemData.finalWeight.ToString(CultureInfo.InvariantCulture);
        }

        private void FillDetails(WearableObject wearable)
        {
            _detailsSection.Clear();
            
            // All effects provided by wearable item
            var effects = wearable.wearableData.effects
                .Select(effect => effect.GetSimpleDescription())
                .ToArray();
            if (!effects.IsNullOrEmpty()) _details.Add(new DetailsElement(_detailsSection, null, effects));
            
            _detailsSection.style.display = _detailsSection.childCount == 0 ? DisplayStyle.None : DisplayStyle.Flex;
        }
    }
}