using System.Collections.Generic;
using Intrepid.Diagnostics;
using Intrepid.GameManagers;
using Intrepid.Gameplay.Journey.Messages.Events;
using Intrepid.Gameplay.Prototyping;
using Intrepid.SimpleEvents;
using Intrepid.Utilities;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Intrepid.Gameplay.Journey
{
    public class StageManager : EventListener
    {
        [GroupConfigurations, SerializeField] private StageTag stageTag;
        [GroupDebug, SerializeField, ReadOnly] private List<InteractableSaveStationModelPrototype> saveStations;
        [GroupDebug, SerializeField, ReadOnly] private List<InteractableSocketModelPrototype> sockets;
        
        private Dictionary<string, InteractableSocketModelPrototype> SocketMap { get; } = new();
        
        public StageTag StageTag
        {
            get => stageTag;
            set => stageTag = value;
        }
        
        protected override void InitializeVariables()
        {
            Refresh();
        }

        protected override void OnBootstrap()
        {
        }

        protected override void Subscriptions()
        {
            Subscribe<ChangeStageLandingOnStageStepEvent>(e =>
            {
                if (SocketMap.TryGetValue(e.DestinyEndpoint, out var stageSocket))
                {
                    Proxy.Instance.EventBus.Raise(new StageDispatchDeploymentPointEvent
                    {
                        DeploymentPoint = stageSocket.DeploymentPoint,
                        DeploymentDirection = stageSocket.DeploymentDirection,
                    });
                    return;
                }
                
                DLogger.LogError($"No stage socket found for endpoint {e.DestinyEndpoint}");
            });
        }

        [GroupDebug, Button(ButtonSizes.Medium)]
        private void Refresh()
        {
            sockets.Clear();
            saveStations.Clear();
            
            SocketMap.Clear();

            foreach (var interactable in GetComponentsInChildren<InteractableModelPrototype>())
            {
                interactable.SetStageManager(this);
                switch (interactable)
                {
                    case InteractableSocketModelPrototype socket:
                        sockets.Add(socket);
                        SocketMap.Add(socket.EndpointId, socket);
                        break;
                    case InteractableSaveStationModelPrototype saveStation:
                        saveStations.Add(saveStation);
                        break;
                }
            }
        }
    }
}