using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace IStalk.Data
{
    public class ItemDatabase : MonoBehaviour
    {
        public static ItemDatabase Instance { get; private set; }

        private Dictionary<string, ItemData_SO> _lootItems = new();
        private Dictionary<string, ShrineItemData_SO> _shrineItems = new();
        private Dictionary<string, TrapData_SO> _traps = new();
        private Dictionary<string, RoomNode_SO> _rooms = new();
        private Dictionary<string, WearableData_SO> _wearables = new();
        private Dictionary<string, EyeType_SO> _eyeTypes = new();

        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }
            Instance = this;
            DontDestroyOnLoad(gameObject);
            LoadAll();
        }

        private void LoadAll()
        {
            foreach (var item in Resources.LoadAll<ItemData_SO>("Items/Loot"))
                _lootItems[item.itemId] = item;

            foreach (var item in Resources.LoadAll<ShrineItemData_SO>("Items/Shrine"))
                _shrineItems[item.itemId] = item;

            foreach (var trap in Resources.LoadAll<TrapData_SO>("Items/Traps"))
                _traps[trap.trapId] = trap;

            foreach (var room in Resources.LoadAll<RoomNode_SO>("Items/Rooms"))
                _rooms[room.roomId] = room;

            foreach (var wearable in Resources.LoadAll<WearableData_SO>("Items/Wearables"))
                _wearables[wearable.wearableId] = wearable;

            foreach (var eyeType in Resources.LoadAll<EyeType_SO>("EyeTypes"))
                _eyeTypes[eyeType.typeId] = eyeType;

            Debug.Log($"[ItemDatabase] Loaded {_lootItems.Count} loot, {_shrineItems.Count} shrine, {_traps.Count} traps, {_rooms.Count} rooms, {_wearables.Count} wearables, {_eyeTypes.Count} eye types");
        }

        public ItemData_SO GetLootItem(string id) => _lootItems.GetValueOrDefault(id);
        public ShrineItemData_SO GetShrineItem(string id) => _shrineItems.GetValueOrDefault(id);
        public TrapData_SO GetTrap(string id) => _traps.GetValueOrDefault(id);
        public RoomNode_SO GetRoom(string id) => _rooms.GetValueOrDefault(id);

        public IReadOnlyCollection<ItemData_SO> AllLootItems => _lootItems.Values;
        public IReadOnlyCollection<RoomNode_SO> AllRooms => _rooms.Values;
        public IReadOnlyCollection<WearableData_SO> AllWearables => _wearables.Values;
        public IReadOnlyCollection<EyeType_SO> AllEyeTypes => _eyeTypes.Values;

        public WearableData_SO GetWearable(string id) => _wearables.GetValueOrDefault(id);
        public EyeType_SO GetEyeType(string id) => _eyeTypes.GetValueOrDefault(id);

        public List<RoomNode_SO> GetRoomsWithLootSlots() =>
            _rooms.Values.Where(r => r.lootSpawnSlots > 0).ToList();

        public List<RoomNode_SO> GetRoomsByCategory(RoomCategory category) =>
            _rooms.Values.Where(r => r.category == category).ToList();

        public List<ItemData_SO> GetLootByRarity(Rarity rarity) =>
            _lootItems.Values.Where(i => i.rarity == rarity).ToList();
    }
}
