using System;
using System.Collections.Generic;
using System.Linq;
using Intrepid.Diagnostics;
using Intrepid.Integration.Persistence.DTOs;
using Intrepid.Utilities;
using UnityEngine;

namespace Intrepid.Integration.Persistence
{
    [CreateAssetMenu(fileName = "Storage Assembler", menuName = "GON/Services/Storage Assembler")]
    public class StorageAssembler : SingletonScriptableObject<StorageAssembler>
    {
        private List<IDataStorage> DataStores { get; } = new();
        
        protected override void WhenInstantiate(StorageAssembler singleton)
        {
            base.WhenInstantiate(singleton);
            DataStores.Clear();
        }

        public void Register(IDataStorage handler)
        {
            if (handler is null) return;
            DataStores.Add(handler);
        }
        
        public void Unregister(IDataStorage handler)
        {
            if (handler is null) return;
            DataStores.Remove(handler);
        }

        public void TakeSnapshot(GameSlotDTO gameSlot)
        {
            var orderedHandlers = DataStores.OrderBy(s => s.Order).ToList();
            ValidateSnapshotData();
            orderedHandlers.ForEach(s => s.MarshalData(gameSlot));
            
            return;

            void ValidateSnapshotData()
            {
                var failValidation = false;
                foreach (var handler in orderedHandlers)
                {
                    if (!handler.IsDataValid(out var errors))
                    {
                        DLogger.LogError($"Errors occurred while validating saving data for handler {handler.GetType().Name}: {string.Join(", ", errors)}");
                        failValidation = true;
                    }
                }
                if (failValidation)
                {
                    throw new Exception("Validation failed for one or more saving snapshot handlers.");
                }
            }
        }
    }
}