using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using VOID.Generic.Objects.Abstract;
using VOID.UserInterface;
using VOID.UserInterface.Game;
using VOID.UserInterface.Game.Party;
using VOID.UserInterface.Game.Util;
using VOID.ScriptableObjects;
using VOID.ScriptableObjects.Abilities;

namespace VOID.Generic.Player.Util
{
    public class SelectUtilResult
    {
        public bool hit { get; private set; }
        public bool onUI { get; private set; }
        
        // UI Component directly under cursor - only one of these
        public readonly SlotUI slotUI;
        public readonly UnitPortraitUI unitPortraitUI;
        public readonly StatusUI statusUI;
        
        // All UI Components behind - usually one of these
        public AbilityBookUI abilityBookUI { get; private set; }
        public ActionBarSlotsUI actionBarSlotsUI { get; private set; }
        public BackpackUI backpackUI { get; private set; }
        public ContainerUI containerUI { get; private set; }
        public EquipmentUI equipmentUI { get; private set; }
        public OtherUnitBackpackUI otherUnitBackpackUI { get; private set; }
        public PartyUI partyUI { get; private set; }
        
        // Clicked position or clicked object's position
        public readonly Vector3 position;
        
        // Clicked object , ability or status
        public readonly AbstractObject selectObject;
        public readonly BasicAbility selectAbility;
        public readonly BasicStatus selectStatus;

        public SelectUtilResult(Vector3 position)
        {
            hit = position != default;
            onUI = false;
            this.position = position;
        }

        public SelectUtilResult(Vector3 position, AbstractObject abstractObject)
        {
            hit = abstractObject;
            onUI = false;
            this.position = position;
            selectObject = abstractObject;
        }

        public SelectUtilResult(SlotUI slotUI)
        {
            hit = slotUI.ability || slotUI.item;
            onUI = true;
            this.slotUI = slotUI;
            
            // Position to select:
            // - in case of ItemObject, select its position
            // - in case of BasicAbility, select caster's position (player's active unit)
            if (slotUI.item) position = slotUI.item.transform.position;
            else if (PlayerController.current.activeUnit) position = PlayerController.current.activeUnit.transform.position;
            
            if (slotUI.ability) selectAbility = slotUI.ability;
            if (slotUI.item) selectObject = slotUI.item;
        }

        public SelectUtilResult(UnitPortraitUI unitPortraitUI)
        {
            hit = unitPortraitUI.unit;
            onUI = true;
            this.unitPortraitUI = unitPortraitUI;
            position = unitPortraitUI.unit.transform.position;
            selectObject = unitPortraitUI.unit;
        }

        public SelectUtilResult(StatusUI statusUI)
        {
            hit = statusUI.status;
            onUI = true;
            this.statusUI = statusUI;
            selectStatus = statusUI.status;
        }

        public SelectUtilResult()
        {
            onUI = false;
            hit = false;
        }

        public SelectUtilResult WithUI(List<VisualElement> cachedElements = null)
        {
            if (!onUI) return this;
            abilityBookUI = GameUI.current.PickComponentUI<AbilityBookUI>(cachedElements); 
            actionBarSlotsUI = GameUI.current.PickComponentUI<ActionBarSlotsUI>(cachedElements); 
            backpackUI = GameUI.current.PickComponentUI<BackpackUI>(cachedElements); 
            containerUI = GameUI.current.PickComponentUI<ContainerUI>(cachedElements); 
            equipmentUI = GameUI.current.PickComponentUI<EquipmentUI>(cachedElements); 
            otherUnitBackpackUI = GameUI.current.PickComponentUI<OtherUnitBackpackUI>(cachedElements); 
            partyUI = GameUI.current.PickComponentUI<PartyUI>(cachedElements);
            onUI = true;
            return this;
        }
    }
}