using Cirno.Scripts.Resources;
using Godot;

namespace Cirno.Scripts.UI;

public partial class WeaponAmmoCounter : Container
{
    public LootItem Item { get; private set; }
    
    [Export]
    public TextureRect Icon { get; private set; }
    
    [Export]
    public TextureRect AmmoIcon { get; private set; }
    
    // The actual ammo label
    [Export] public Label TotalAmmoLabel { get; private set; }
    
    // Item count label
    [Export] public Label LoadedAmmoLabel { get; private set; }

    public void Init(LootItem item)
    {
        Item = item;
        
        // If it has icon show it
        // if it has count show it
        // if it has ammo show it
        
        // What's the point of having count and ammo without icon?

        if (!item.UiType.HasFlag(UiItemType.Icon))
        {
            Icon.Hide();
        }
        else
        {
            Icon.Texture = item.InventorySprite;
        }

        if (!item.UiType.HasFlag(UiItemType.Count))
        {
            LoadedAmmoLabel.Hide();
        }
        
        if (item.UiType.HasFlag(UiItemType.Ammo))
        {
            InventoryManager.Instance.LoadedAmmoChanged += OnInstanceOnLoadedAmmoChanged;
            
            if (string.IsNullOrWhiteSpace(item.WeaponData?.AmmoKey))
            {
                TotalAmmoLabel.Hide();
                AmmoIcon.Hide();
                return;
            }

            if (InventoryManager.Instance.TryGetItem(item.WeaponData?.AmmoKey, out var ammoItem))
            {
                AmmoIcon.Texture = ammoItem.Item.InventorySprite;
            }
            UpdateAmmoCounter();
            
            // Register this only if there's ammo
            InventoryManager.Instance.TotalAmmoChanged += OnInstanceOnTotalAmmoChanged;
        }
        else
        {
            AmmoIcon.Hide();
            TotalAmmoLabel.Hide();
            
            // Here sync the item count if it has no ammo but has count
            if (item.UiType.HasFlag(UiItemType.Count))
            {
                InventoryManager.Instance.ItemAdded += ItemAmountChanged;
                InventoryManager.Instance.ItemRemoved += ItemAmountRemoved;
            }
            
        }
        
    }

    private void ItemAmountChanged(LootItem item, int currentAmount)
    {
        if (item.ItemKey == Item.ItemKey)
        {
            LoadedAmmoLabel.Text = currentAmount.ToString();
        }
    }

    private void ItemAmountRemoved(string key, int currentAmount)
    {
        if (key == Item.ItemKey)
        {
            LoadedAmmoLabel.Text = currentAmount.ToString();
        }
    }

    private void OnInstanceOnLoadedAmmoChanged(StringName weaponKey, int count)
    {
        if (weaponKey != Item.WeaponData.ItemKey) return;
        LoadedAmmoLabel.Text = count.ToString();
    }

    private void OnInstanceOnTotalAmmoChanged(StringName ammoKey, int count)
    {
        if (ammoKey != Item.WeaponData.AmmoKey) return;
        TotalAmmoLabel.Text = count.ToString();
    }

    public void Delete()
    {
        InventoryManager.Instance.LoadedAmmoChanged -= OnInstanceOnLoadedAmmoChanged;
        InventoryManager.Instance.TotalAmmoChanged -= OnInstanceOnTotalAmmoChanged;
        InventoryManager.Instance.ItemAdded -= ItemAmountChanged;
        InventoryManager.Instance.ItemRemoved -= ItemAmountRemoved;
        QueueFree();
    }

    private void UpdateAmmoCounter()
    {
        TotalAmmoLabel.Text = InventoryManager.Instance.GetItemCount(Item.WeaponData.AmmoKey).ToString();
    }
}