using System;
using System.Text;
using UnityEngine;

namespace Davanci.Nexus
{
    // Loads once at launch, saves on pause/quit. Wire CollectSave / ApplyLoad from the game.
    // If ApplyLoad is set after the launch load finishes, the cached result is replayed.
    public sealed class NexusCloudSaveRunner : SingletonMB<NexusCloudSaveRunner>
    {
        public static Func<byte[]> CollectSave;

        public static void Bind(Func<string> save, Action<string> load)
        {
            CollectSave = () =>
            {
                string s = save?.Invoke();
                return s == null ? null : Encoding.UTF8.GetBytes(s);
            };
            ApplyLoad = res =>
                load?.Invoke(res.HasData ? Encoding.UTF8.GetString(res.Payload) : null);
        }

        static Action<NexusSaveResult> _applyLoad;
        static bool _hasResult;
        static NexusSaveResult _result;

        public static Action<NexusSaveResult> ApplyLoad
        {
            get => _applyLoad;
            set
            {
                _applyLoad = value;
                if (_hasResult) value?.Invoke(_result);
            }
        }

        protected override void Initialize()
        {
            _hasResult = false;
            NexusCloudSave.LoadResult(res =>
            {
                _result = res;
                _hasResult = true;
                _applyLoad?.Invoke(res);
            });
        }

        public static void Save(Action<bool> onDone = null)
        {
            if (CollectSave == null) { onDone?.Invoke(false); return; }
            byte[] data = CollectSave();
            if (data == null) { onDone?.Invoke(false); return; }
            NexusCloudSave.Save(data, onDone);
        }

        void OnApplicationPause(bool paused)
        {
            if (paused) Save();
        }

        protected override void OnApplicationQuit()
        {
            Save();
            base.OnApplicationQuit();
        }
    }
}
