using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace StandardScene.Chained
{
    /// <summary>
    /// 可用于区分 Delivery 各生命周期事件的枚举。
    /// </summary>
    public enum DeliveryEventType
    {
        OnStart,
        DoneFetch,
        DonePut,
        DoneMission,
        Failed,
        OnTerminated
    }

    /// <summary>
    /// 全局任务回调注册表：通过 (事件类型, key) 注册/解析各阶段回调，便于持久化和恢复。
    /// </summary>
    public static class DeliveryCallbackRegistry
    {
        private static readonly Dictionary<(DeliveryEventType, string), Delegate> _callbacks = new();

        private static void RegisterInternal(DeliveryEventType type, string key, Delegate callback)
        {
            if (string.IsNullOrWhiteSpace(key) || callback == null) return;
            _callbacks[(type, key)] = callback;
        }

        private static T ResolveInternal<T>(DeliveryEventType type, string key) where T : class
        {
            if (key == null) return null;
            return _callbacks.TryGetValue((type, key), out var d) ? d as T : null;
        }

        public static void RegisterOnStart(string key, Action<ChainedDeliveryMission.Delivery> callback) =>
            RegisterInternal(DeliveryEventType.OnStart, key, callback);

        public static void RegisterDoneFetch(string key, Action<ChainedDeliveryMission.Delivery> callback) =>
            RegisterInternal(DeliveryEventType.DoneFetch, key, callback);

        public static void RegisterDonePut(string key, Action<ChainedDeliveryMission.Delivery> callback) =>
            RegisterInternal(DeliveryEventType.DonePut, key, callback);

        public static void RegisterDoneMission(string key, Action<ChainedDeliveryMission.Delivery> callback) =>
            RegisterInternal(DeliveryEventType.DoneMission, key, callback);

        public static void RegisterFailed(string key, Action<ChainedDeliveryMission.Delivery> callback) =>
            RegisterInternal(DeliveryEventType.Failed, key, callback);

        public static void RegisterOnTerminated(string key, Func<ChainedDeliveryMission.Delivery, string, Task<int>> callback) =>
            RegisterInternal(DeliveryEventType.OnTerminated, key, callback);

        public static Action<ChainedDeliveryMission.Delivery> ResolveOnStart(string key) =>
            ResolveInternal<Action<ChainedDeliveryMission.Delivery>>(DeliveryEventType.OnStart, key);

        public static Action<ChainedDeliveryMission.Delivery> ResolveDoneFetch(string key) =>
            ResolveInternal<Action<ChainedDeliveryMission.Delivery>>(DeliveryEventType.DoneFetch, key);

        public static Action<ChainedDeliveryMission.Delivery> ResolveDonePut(string key) =>
            ResolveInternal<Action<ChainedDeliveryMission.Delivery>>(DeliveryEventType.DonePut, key);

        public static Action<ChainedDeliveryMission.Delivery> ResolveDoneMission(string key) =>
            ResolveInternal<Action<ChainedDeliveryMission.Delivery>>(DeliveryEventType.DoneMission, key);

        public static Action<ChainedDeliveryMission.Delivery> ResolveFailed(string key) =>
            ResolveInternal<Action<ChainedDeliveryMission.Delivery>>(DeliveryEventType.Failed, key);

        public static Func<ChainedDeliveryMission.Delivery, string, Task<int>> ResolveOnTerminated(string key) =>
            ResolveInternal<Func<ChainedDeliveryMission.Delivery, string, Task<int>>>(DeliveryEventType.OnTerminated, key);
    }
}

