﻿using System;
using System.Collections.Generic;
using JLGames.RocketDriver.CSharp.Service;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Cfg.CfgConst;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.ConfigData;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.GM;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.Material;
using JLGames.RocketDriver.Samples.RpgMaterialDemo.Service.MaterialExtend.Exchange;

namespace JLGames.RocketDriver.Samples.RpgMaterialDemo.Service
{
    internal static class ServiceRegister
    {
        private static readonly List<int> m_MaterialTypes = new List<int>();
        private static bool m_Registered = false;

        /// <summary>
        /// 取全部材料类型
        /// </summary>
        public static int[] RegisteredMaterialTypes => m_MaterialTypes.ToArray();

        /// <summary>
        /// 检查材料类型是否存在
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool CheckMaterialExist(int type)
        {
            return m_MaterialTypes.Contains(type);
        }

        internal static void RegisterServices()
        {
            if (m_Registered) return;
            m_MaterialTypes.Clear();
            RegisterInfraServices();
            RegisterBusinessConfigs();
            RegisterPostConfigs();
            m_Registered = true;
        }

        private static void RegisterInfraServices()
        {
            RegisterService(ServiceNames.ConfigData, new ConfigDataService());
        }

        private static void RegisterBusinessConfigs()
        {
            // 材料相关
            RegisterMaterialService(ConstMaterialType.Resource, new MaterialResourceService());
            RegisterMaterialService(ConstMaterialType.Item, new MaterialItemService());
            RegisterMaterialService(ConstMaterialType.Giftbag, new MaterialGiftbagService());
            // 游戏业务
            RegisterService(ServiceNames.Exchange, new ExchangeService());
            // 以下调试用
            RegisterService(ServiceNames.Gm, new GmService());
        }

        private static void RegisterPostConfigs()
        {
        }

        private static void RegisterService(string serviceName, IService serviceImpl, params object[] args)
        {
            ServiceConfig.Shared.AddConfig(new ServiceInfo(serviceName, serviceImpl, args));
        }

        private static void RegisterMaterialService(int materialType, IService serviceImpl, params object[] args)
        {
            if (m_MaterialTypes.Contains(materialType)) throw new Exception($"Repeat registration at {materialType}!");
            m_MaterialTypes.Add(materialType);
            RegisterService(GetMaterialServiceName(materialType), serviceImpl, args);
        }

        internal static string GetMaterialServiceName(int materialType)
        {
            return $"ServiceNames.Material_{materialType}";
        }
    }
}