using JiShe.CollectBus.Common.Consts;
using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Extensions;
using JiShe.CollectBus.Common.Models;
using JiShe.CollectBus.IotSystems.Protocols;
using JiShe.CollectBus.Protocol.Models;
using JiShe.CollectBus.Protocol.T37612012;
using JiShe.CollectBus.Protocol.T37612012.SendData;
using JiShe.CollectBus.Protocol.T6452007.SendData;
using Mapster;
using Microsoft.Extensions.Logging;
using TouchSocket.Sockets;

namespace JiShe.CollectBus.Protocol.T6452007
{
    /// <summary>
    /// T6452007协议插件
    /// </summary>
    public class T6452007ProtocolPlugin : T37612012ProtocolPlugin
    {
        private readonly ILogger<T6452007ProtocolPlugin> _logger;
         
        public readonly Dictionary<string, Telemetry6452007PacketBuilder.T6452007Delegate> T645ControlHandlers;

        /// <summary>
        /// Initializes a new instance of the <see cref="T6452007ProtocolPlugin"/> class.
        /// </summary>
        /// <param name="serviceProvider">The service provider.</param>
        public T6452007ProtocolPlugin(IServiceProvider serviceProvider, ILogger<T6452007ProtocolPlugin> logger, ITcpService tcpService) : base(serviceProvider, logger, tcpService)
        {
            _logger = logger;
            T645ControlHandlers = Telemetry6452007PacketBuilder.T645ControlHandlers;
        }

        public sealed override ProtocolInfo Info => new(nameof(T6452007ProtocolPlugin), "376.1/645-2007", "TCP", "376.1/645-2007协议", "DTS1980");

        public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
        {
            //TODO:645解析报文
            //TB3761? tB3761 = Analysis3761(messageReceived);
            //if (tB3761 != null)
            //{
            //    if (tB3761.AFN_FC?.AFN == (int)AFN.链路接口检测)
            //    {
            //        if (tB3761.A == null || tB3761.A.Code.IsNullOrWhiteSpace() || tB3761.A.A3?.D1_D7 == null || tB3761.SEQ?.PSEQ == null)
            //        {
            //            _logger.LogError($"解析AFN.链路接口检测报文失败,报文：{messageReceived},TB3761:{tB3761.Serialize()}");
            //        }
            //        else
            //        {
            //            if (tB3761.DT?.Fn == (int)FN.登录)
            //            {
            //                // 登录回复
            //                if (tB3761.SEQ.CON == (int)CON.需要对该帧进行确认)
            //                    await LoginAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ);
            //            }
            //            else if (tB3761.DT?.Fn == (int)FN.心跳)
            //            {
            //                // 心跳回复
            //                //心跳帧有两种情况：
            //                //1. 集中器先有登录帧，再有心跳帧
            //                //2. 集中器没有登录帧，只有心跳帧
            //                await HeartbeatAsync(client, messageReceived, tB3761.A.Code, tB3761.A.A3?.D1_D7, tB3761.SEQ?.PSEQ);
            //            }
            //        }

            //    }
            //    await OnTcpNormalReceived(client, tB3761);
            //}
            //return (tB3761 as T)!;
            return null;
        }

        /// <summary>
        /// 组装报文
        /// </summary>
        /// <param name="request">报文构建参数</param>
        /// <returns></returns>
        public override async Task<ProtocolBuildResponse> BuildAsync(ProtocolBuildRequest request)
        {
            if (request == null)
            {
                _logger.LogError($"{nameof(ProtocolBuildResponse)} 报文构建失败，参数为空");
                return new ProtocolBuildResponse();
            }
            var itemCodeArr = request.ItemCode.Split('_');
            var aFNStr = itemCodeArr[0];
            var aFN = (AFN)aFNStr.HexToDec();
            var fn = int.Parse(itemCodeArr[1]);
            Telemetry3761PacketResponse builderResponse = null;

            List<string> dataUnit = new List<string>();
            //数据转发场景 10H_F1
            if (request.ItemCode == T37612012PacketItemCodeConst.AFN10HFN01H && request.SubProtocolRequest != null && string.IsNullOrWhiteSpace(request.SubProtocolRequest.ItemCode) == false)
            {
                var t645PacketHandlerName = $"C{request.SubProtocolRequest.ItemCode}_Send";
                Telemetry6452007PacketResponse t645PacketResponse = null;

                if (T645ControlHandlers != null && T645ControlHandlers.TryGetValue(t645PacketHandlerName
                  , out var t645PacketHandler))
                {
                    t645PacketResponse = t645PacketHandler(new Telemetry6452007PacketRequest()
                    {
                        MeterAddress = request.SubProtocolRequest.MeterAddress,
                        Password = request.SubProtocolRequest.Password,
                        ItemCode = request.SubProtocolRequest.ItemCode,
                    });
                }

                if (t645PacketResponse != null)
                {
                    dataUnit = t645PacketResponse.Data;
                }
            }

            string afnMethonCode = $"AFN{aFNStr}_Fn_Send";
            if (base.T3761AFNHandlers != null && base.T3761AFNHandlers.TryGetValue(afnMethonCode
                    , out var handler))
            {
                builderResponse = handler(new Telemetry3761PacketRequest()
                {
                    FocusAddress = request.FocusAddress,
                    Fn = fn,
                    Pn = request.Pn,
                    DataUnit = dataUnit,
                });
            }

            if (builderResponse == null)
            {
                return new ProtocolBuildResponse();
            }

            var result = builderResponse.Adapt<ProtocolBuildResponse>();
            result.IsSuccess = true;

            return await Task.FromResult(result);
        } 
    }
}
