using DirectService.Tools;
using JLHHJSvr.BLL;
using JLHHJSvr.Com.Model;
using LJLib;
using LJLib.DAL.SQL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
namespace JLHHJSvr.Helper
{
    internal sealed class CacheHelper : HelperBase
    {
        #region 基础资料Mapping
        /// <summary>
        /// 弹簧资料
        /// </summary>
        public class SpringMapping : ICacheMapping<int, u_spring>
        {
            public u_spring GetInstance(SqlCommand cmd, int springid)
            {
                var instance = new u_spring() { springid = springid };
                DbSqlHelper.SelectOne(cmd, instance, "line_diameter,gram_weight,height,center_diameter,caliber,cyclenum,roll_width,roll_length,arrangement_width,arrangement_height,springtypeid");
                return instance;
            }
        }
        /// <summary>
        /// 部门资料
        /// </summary>
        public class DeptMapping : ICacheMapping<int, u_dept>
        {
            public u_dept GetInstance(SqlCommand cmd, int deptid)
            {
                var instance = new u_dept() { deptid = deptid };
                DbSqlHelper.SelectOne(cmd, instance, "pricelistid,profitrate,moneyrate,discount,taxes_rate,managerate,com_profitrate,dannum1_rate,dannum2_rate,dannum3_rate,dannum4_rate");
                return instance;
            }
        }

        public class MtrlMapping : ICacheMapping<int, u_mtrl_price>
        {
            public u_mtrl_price GetInstance(SqlCommand cmd, int mtrlid)
            {
                var instance = new u_mtrl_price() { mtrlid = mtrlid };
                DbSqlHelper.SelectOne(cmd, instance, "mtrlid,mtrltype,name,priceunit,shrinkage,gram_weight,cloth_width,if_inputqty,if_areaprice,createtime,createby,thickness,dscrp,erp_mtrlid,fjcnt,isuse,lastdate,handtype,if_subspecs,extra_cost,is_singleqty");
                return instance;
            }
        }
        #endregion

        #region 获取数据
        private static readonly Dictionary<Type, object> _cacheServiceRegistry = new Dictionary<Type, object>();

        public TEntity GetData<TEntity, TMapping>(object key)
        where TEntity : class, new()
        where TMapping : new()
        {
            // 找到接口中的 TKey
            var mappingType = typeof(TMapping);
            var iface = mappingType.GetInterfaces()
                .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICacheMapping<,>));

            if (iface == null)
                throw new InvalidOperationException($"{mappingType.Name} must implement ICacheMapping<TKey, TValue>");

            var keyType = iface.GetGenericArguments()[0];

            // 获取私有泛型方法
            var method = typeof(CacheHelper).GetMethod(nameof(GetDataInternal), BindingFlags.Instance | BindingFlags.NonPublic);
            var gm = method.MakeGenericMethod(keyType, typeof(TEntity), mappingType);

            // 调用并返回（Invoke 返回 object）
            return (TEntity)gm.Invoke(this, new object[] { key });
        }

        private TValue GetDataInternal<TKey, TValue, TMapping>(object key)
            where TMapping : ICacheMapping<TKey, TValue>, new()
            where TValue : class, new()
        {
            var mappingType = typeof(TMapping);

            if (!_cacheServiceRegistry.TryGetValue(mappingType, out var serviceObj))
            {
                // 没有就创建
                var cacheService = new CacheService<TKey, TValue>(new GenericLoader<TKey, TValue>(new TMapping()));
                _cacheServiceRegistry.Add(mappingType, cacheService);
                serviceObj = cacheService;
            }

            var service = (ICacheService<TKey, TValue>)serviceObj;
            return service.Get(cmd, (TKey)key);
        }
        public void RemoveData<TMapping, TEntity>(object key)
        where TEntity : class, new()
        where TMapping : new()
        {
            // 找到接口中的 TKey
            var mappingType = typeof(TMapping);
            var iface = mappingType.GetInterfaces()
                .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICacheMapping<,>));

            if (iface == null)
                throw new InvalidOperationException($"{mappingType.Name} must implement ICacheMapping<TKey, TValue>");

            var keyType = iface.GetGenericArguments()[0];

            // 检查键类型是否匹配
            if (!keyType.IsInstanceOfType(key))
                throw new ArgumentException($"Key type {keyType.Name} does not match expected type");

            // 获取私有泛型方法
            var method = typeof(CacheHelper).GetMethod(nameof(RemoveInternal), BindingFlags.Instance | BindingFlags.NonPublic);
            var gm = method.MakeGenericMethod(keyType, typeof(TEntity), mappingType);

            // 调用方法
            gm.Invoke(this, new object[] { key });
        }

        private void RemoveInternal<TKey, TValue, TMapping>(object key)
            where TMapping : ICacheMapping<TKey, TValue>, new()
            where TValue : class, new()
        {
            var mappingType = typeof(TMapping);

            if (!_cacheServiceRegistry.TryGetValue(mappingType, out var serviceObj)) return;
            var service = (ICacheService<TKey, TValue>)serviceObj;
            service.Remove((TKey)key);
        }
        #endregion
    }
}
