using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using DeviceDetectorNET.Class.Device;
using JiShe.CollectBus.Common.BuildSendDatas;
using JiShe.CollectBus.Common.Consts;
using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Extensions;
using JiShe.CollectBus.Common.Helpers;
using JiShe.CollectBus.Common.Models;
using JiShe.CollectBus.EnergySystem.Dto;
using JiShe.CollectBus.FreeSql;
using JiShe.CollectBus.IotSystems.PrepayModel;
using JiShe.CollectBus.IotSystems.Records;
using JiShe.CollectBus.Kafka.Producer;
using JiShe.CollectBus.Protocol.Contracts;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Volo.Abp.Domain.Repositories;
using YamlDotNet.Core;

namespace JiShe.CollectBus.EnergySystem
{
    public class EnergySystemAppService: CollectBusAppService,IEnergySystemAppService
    {
        private readonly IRepository<FocusRecord, Guid> _focusRecordRepository;
        private readonly IRepository<CsqRecord,Guid> _csqRecordRepository;
        private readonly IRepository<ConrOnlineRecord,Guid>  _conrOnlineRecordRepository;
        private readonly IProducerService _producerService;

        public EnergySystemAppService(IRepository<FocusRecord, Guid> focusRecordRepository, IRepository<CsqRecord, Guid> csqRecordRepository,
            IRepository<ConrOnlineRecord, Guid> conrOnlineRecordRepository, IProducerService producerService)
        {
            _focusRecordRepository = focusRecordRepository;
            _csqRecordRepository = csqRecordRepository;
            _conrOnlineRecordRepository = conrOnlineRecordRepository;
            _producerService = producerService;
        }

        /// <summary>
        /// 电表、水表阀控 透明转发
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Handmould/TranspondSend_10_98")]
        public async Task<BaseResultDto<ValveControlOutput>> ValveControl(ValveControlInput input)
        {
            var result = new BaseResultDto<ValveControlOutput>();

            byte[] bytes = null;
            var state = input.TripState == 0 ? true : false;
            var address = $"{input.AreaCode}{input.Address}";
            if (input.MeterType == 1)
            {
                var ammeter = await SqlProvider.Instance.Change(DbEnum.EnergyDB).Select<Vi_BaseAmmeterInfo>().Where(d => d.ID == input.AmmeterId).FirstAsync();
                if (ammeter == null) return result;

                var dataUnit =
                    Build645SendData.BuildAmmeterValveControlSendDataUnit(ammeter.Address, "", ammeter.Password,
                        state);
                bytes = Build3761SendData.BuildTransparentForwardingSendCmd(address, ammeter.PortNumber ?? 2, ammeter.BaudRate, dataUnit);
            }
            else if(input.MeterType == 2)
            {
                //TODO:水表阀控
            }

            if (bytes == null)
                return result;

            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});

            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });
            result.Status = true;
            result.Msg = "操作成功";
            result.Data.ValidData = true;
            return result;
        }

        /// <summary>
        /// 批量抄读时段 透明转发
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/TranspondSend_10_94")]
        public async Task<BaseResultDto<ReadTimeOutput>> ReadTime(ReadTimeInput input)
        {
            var result = new BaseResultDto<ReadTimeOutput>
            {
                Data = new ReadTimeOutput()
            };

            var ammeter = await SqlProvider.Instance.Change(DbEnum.EnergyDB).Select<Vi_BaseAmmeterInfo>().Where(d => d.ID == input.AmmeterId).FirstAsync();
            if (ammeter == null) return result;

            var address = $"{input.AreaCode}{input.Address}";
            var bytesList = Build3761SendData.BuildReadMeterTimeSetSendCmd(address, ammeter.Code, ammeter.Address, ammeter.Password,
                ammeter.PortNumber ?? 2, ammeter.BaudRate);

            foreach (var bytes in bytesList)
            {
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});

                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });

            }

            return result;
        }

        /// <summary>
        /// 档案下发 AFN:04 FN:10
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Handmould/IssueArchives")]
        public async Task<BaseResultDto<AmmeterArchivesDownOutput>> AmmeterArchivesDown(AmmeterArchivesDownInput input)
        {
            var result = new BaseResultDto<AmmeterArchivesDownOutput>();
            var address = $"{input.AreaCode}{input.Address}";
            var meterParameters = input.Details.Data.Select(it => new AmmeterParameter()
            {
                SerialNumber = it.SerialNumber,
                Pn = it.Pn,
                BaudRate = Build3761SendData.GetBaudreate(it.Rate.ToString()),
                Port = it.Port,
                ProtocolType = Build3761SendData.GetProtocolType(it.AgreementType),
                Address = it.Addrress,
                Password = it.Password.ToString(),
                RateNumber = it.RatesCount,
                IntegerBitNumber = it.IntegerCount,
                DecimalBitNumber = it.DecimalCount,
                CollectorAddress = it.GatherAddress,
                //UserCategoryNumber = it.UserBigNumber,
                //UserSubclassNumber = it.UserSmallNumber
                
            }).ToList();
            var bytes = Build3761SendData.BuildAmmeterParameterSetSendCmd(address, meterParameters);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });
            result.Status = true;
            result.Msg = "操作成功";
            result.Data.ValidData = true;
            return result;
        }

        /// <summary>
        /// 一键匹配 透明转发   
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/ReadMeterAddress_10_105")]
        public async Task<BaseResultDto> AmmeterArchivesMatch(AmmeterArchivesMatchInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";
            foreach (var detail in input.Details.Data)
            {
                var dataUnit = Build645SendData.BuildReadMeterAddressSendDataUnit(detail.MeterAddress);
                var bytes =Build3761SendData.BuildTransparentForwardingSendCmd(address, detail.Port, detail.BaudRate.ToString(), dataUnit, StopBit.Stop1, Parity.None);

                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        [HttpPost("Handmould/EquitDubg")]
        public async Task<BaseResultDto> EquitDubg(EquitDubgInput input)
        {
            var result = new BaseResultDto();
          
            try
            {
                byte[] bytes = null;
                var address = $"{input.AreaCode}{input.Address}";
                bool isManual = !input.AreaCode.Equals("5110");//低功耗集中器不是长连接，在连接的那一刻再发送

                switch (input.ItemCode)
                {
                    case "01_1":
                        bytes = Build3761SendData.BuildConrRebootSendCmd(address);
                        break;
                    case "0C_2":
                        bytes = Build3761SendData.BuildTerminalCalendarClockSendCmd(address);
                        break;
                    case "04_3":
                        if (string.IsNullOrWhiteSpace(input.Data))
                        {
                            result.Status = false;
                            result.Msg = "传入参数错误";
                            return result;
                        }
                        var communicationParametersSetData = JsonConvert.DeserializeObject<CommunicationParametersSetDataInput>(input.Data);
                        var masterIPAndPortArr = communicationParametersSetData.MasterIPandPort.Split(':');
                        var masterIP = masterIPAndPortArr[0];
                        var materPort = masterIPAndPortArr[1];
                        if (!masterIP.IsValidIPv4() || !materPort.IsValidPort())
                        {
                            result.Status = false;
                            result.Msg = "主站IP和端口格式错误";
                            return result;
                        }
                        var backupIPAndPortArr = communicationParametersSetData.BackupIPandPort.Split(':');
                        var backupIP = backupIPAndPortArr[0];
                        var backupPort = backupIPAndPortArr[1];
                        if (!backupIP.IsValidIPv4() || !backupPort.IsValidPort())
                        {
                            result.Status = false;
                            result.Msg = "主站IP和端口格式错误";
                            return result;
                        }

                        bytes = Build3761SendData.BuildCommunicationParametersSetSendCmd(address, masterIP, materPort,
                            backupIP, backupPort, communicationParametersSetData.APN);
                        break;
                    case "05_31":
                        bytes = Build3761SendData.BuildConrCheckTimeSendCmd(address, DateTime.Now, isManual);
                        break;
                    case "0A_10":
                        if (string.IsNullOrWhiteSpace(input.Data))
                        {
                            result.Status = false;
                            result.Msg = "传入参数错误";
                            return result;
                        }
                        var pnList = input.Data.Split(',').Select(int.Parse).ToList();
                        bytes = Build3761SendData.BuildAmmeterParameterReadingSendCmd(address, pnList);
                        break;
                    default:
                        break;
                }

                if (bytes != null)
                {
                    //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                    //{
                    //    //ClientId = messageReceived.ClientId,
                    //    DeviceNo = address,
                    //    Message = bytes,
                    //    Type = IssuedEventType.Data,
                    //    MessageId = Guid.NewGuid().ToString()
                    //});

                    await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                    {
                        //ClientId = messageReceived.ClientId,
                        DeviceNo = address,
                        Message = bytes,
                        Type = IssuedEventType.Data,
                        MessageId = Guid.NewGuid().ToString()
                    });

                    if (isManual)
                    {
                      //等待设备返回结果
                    }
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.Msg = ex.Message;
            }

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }


        /// <summary>
        /// 通讯参数设置 AFN:04 FN:3
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/EquitDubg/CommunicationParametersSet")]
        public async Task<BaseResultDto> CommunicationParametersSet(CommunicationParametersSetInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";
            var masterIPAndPortArr = input.Data.MasterIPandPort.Split(':');
            var masterIP = masterIPAndPortArr[0];
            var materPort = masterIPAndPortArr[1];
            if (!masterIP.IsValidIPv4() || !materPort.IsValidPort())
            {
                result.Status = false;
                result.Msg = "主站IP和端口格式错误";
                return result;
            }
            var backupIPAndPortArr = input.Data.BackupIPandPort.Split(':');
            var backupIP = backupIPAndPortArr[0];
            var backupPort = backupIPAndPortArr[1];
            if (!backupIP.IsValidIPv4() || !backupPort.IsValidPort())
            {
                result.Status = false;
                result.Msg = "主站IP和端口格式错误";
                return result;
            }

            var bytes = Build3761SendData.BuildCommunicationParametersSetSendCmd(address, masterIP, materPort,
                backupIP, backupPort, input.Data.APN);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});

            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 召测时间 AFN:0C FN:2
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/EquitDubg/CallTimeTesting")]
        public async Task<BaseResultDto> CallTimeTesting(CallTimeTestingInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";
          
            var bytes = Build3761SendData.BuildTerminalCalendarClockSendCmd(address);

            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 时间校准 AFN:05 FN:31
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/EquitDubg/TimeAdjust")]
        public async Task<BaseResultDto> TimeAdjust(TimeAdjustInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";
            bool isManual = !input.AreaCode.Equals("5110");//低功耗集中器不是长连接，在连接的那一刻再发送

            var bytes = Build3761SendData.BuildConrCheckTimeSendCmd(address,DateTime.Now, isManual);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 重启终端 AFN:01 FN:1
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/EquitDubg/TerminalRestart")]
        public async Task<BaseResultDto> TerminalRestart(TerminalRestartInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";

            var bytes = Build3761SendData.BuildConrRebootSendCmd(address);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 读取表号 AFN:0A FN:10
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/EquitDubg/ReadMeterNum")]
        public async Task<BaseResultDto<ReadMeterNumOutput>> ReadMeterNum(ReadMeterNumInput input)
        {
            var result = new BaseResultDto<ReadMeterNumOutput>();
           
            var address = $"{input.AreaCode}{input.Address}";
            var pnList = input.Data.Split(',').Select(it => int.Parse(it)).ToList();
            var bytes = Build3761SendData.BuildAmmeterParameterReadingSendCmd(address, pnList);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 随抄
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/IssueCmd")]
        public async Task<BaseResultDto<ReadingOutput>> Reading(ReadingInput input)
        {
            var result = new BaseResultDto<ReadingOutput>();
            var ammeter = await SqlProvider.Instance.Change(DbEnum.EnergyDB).Select<Vi_BaseAmmeterInfo>().Where(d => d.ID == input.AmmeterId).FirstAsync();
            if (ammeter == null || !ammeter.MeterCode.HasValue) return result;
            
            var bytesList = new List<byte[]>();
            var address = $"{input.AreaCode}{input.Address}";
            var itemCodeList = JsonConvert.DeserializeObject<List<string>>(input.ItemCodes);
            foreach (var itemCode in itemCodeList)
            {
                var itemCodeArr = itemCode.Split('_');
                var aFN = (AFN)itemCodeArr[0].HexToDec();
                var fn = int.Parse(itemCodeArr[1]);
                if (aFN == AFN.请求实时数据)
                {
                    var bytes = Build3761SendData.BuildAmmeterReadRealTimeDataSendCmd(address, ammeter.MeterCode.Value, (ATypeOfDataItems)fn);
                    bytesList.Add(bytes);
                }
                else if (aFN == AFN.请求历史数据)
                {
                    var density = (FreezeDensity)input.Density;
                    var bytes = Build3761SendData.BuildAmmeterReadingIIdataTypeItemsSendCmd(address, ammeter.MeterCode.Value, (IIdataTypeItems)fn, density,0);
                    bytesList.Add(bytes);
                }
            }

            foreach (var bytes in bytesList)
            {
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});

                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });

            }
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 设置时间段 透明转发
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/IssueTranspondTimeSet_10_103")]
        public async Task<BaseResultDto> TimeSet(TimeSetInput input)
        {
            var result = new BaseResultDto();

            var ammeter = await SqlProvider.Instance.Change(DbEnum.EnergyDB).Select<Vi_BaseAmmeterInfo>().Where(d => d.ID == input.MeterID).FirstAsync();
            if (ammeter == null) return result;

            //if (string.IsNullOrEmpty(ammeter.BrandType))
            //{
            //    resultMsg.Status = false;
            //    resultMsg.Msg = "电表型号为空";
            //    return resultMsg;
            //}
            //var listData = ProgramModelConfig.ProgramModels;
            //var pm = listData.FirstOrDefault(n => n.Model == ammeter.BrandType);
            //if (pm == null)
            //{
            //    resultMsg.Status = false;
            //    resultMsg.Msg = $"电表{ammeter.AmmerterAddress}型号{ammeter.BrandType}暂不支持时段设置";
            //    return resultMsg;
            //}

            //resultMsg.Status = true;
            //if (pm.IsEnter)
            //{
            //    resultMsg.Data = pm.cmdData;
            //}

            var address = input.FocusCode;
            var timeDataList = input.Data.Select(it => new TimeSetDetail()
            {
                Months = it.Month.Split(',').Select(m => int.Parse(m)).ToArray(),
                Data = it.Data.Select(d => new MutileRateDetail()
                {
                    Rate = d.Rate,
                    Times = d.Times.Select(t => new Times()
                    {
                        StartTime = t.StartTime,
                        EndTime = t.EndTime
                    }).ToList()
                }).ToList()
            }).ToList();
            var bytesList = Build3761SendData.BuildAmmeterSetTimeSetSendCmd(address,ammeter.Address,ammeter.Password,
                ammeter.PortNumber ?? 2, ammeter.BaudRate, timeDataList);

            foreach (var bytes in bytesList)
            {
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 设置自动上报采集项 数据库操作
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/SetAutoItemCode")]
        public async Task<BaseResultDto> AutoReportCollectionItemsSet(AutoReportCollectionItemsSetInput input)
        {
            var result = new BaseResultDto();
            foreach (var code in input.Codes)
            {
                var address = $"{code.AreaCode}{code.Address}";
                var bytes = Build3761SendData.BuildAmmeterReportCollectionItemsSetSendCmd(address,input.Detail.Pn, input.Detail.Unit,input.Detail.Cycle,input.Detail.BaseTime,
                    input.Detail.CurveRatio,input.Detail.Details.Select(it => new PnFn(it.Pn,it.Fn)).ToList());
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 设置自动上报 数据库操作
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/SetAutoUpSwitch")]
        public async Task<BaseResultDto> AutoReportSet(AutoReportSetInput input)
        {
            var result = new BaseResultDto();
            foreach (var code in input.Codes)
            {
                var address = $"{code.AreaCode}{code.Address}";
                var bytes = Build3761SendData.BuildAmmeterAutoUpSwitchSetSendCmd(address, input.Detail.Pn,input.Detail.IsOpen);
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 查询自动上报开启状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/QueryAutoUpSwitch")]
        public async Task<BaseResultDto> QueryAutoReportOpenStatus(QueryAutoReportOpenStatusInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";
            var bytes = Build3761SendData.BuildAmmeterReadAutoUpSwitchSendCmd(address, input.Detail.Pn);
            //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            //{
            //    //ClientId = messageReceived.ClientId,
            //    DeviceNo = address,
            //    Message = bytes,
            //    Type = IssuedEventType.Data,
            //    MessageId = Guid.NewGuid().ToString()
            //});
            await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
            {
                //ClientId = messageReceived.ClientId,
                DeviceNo = address,
                Message = bytes,
                Type = IssuedEventType.Data,
                MessageId = Guid.NewGuid().ToString()
            });
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 批量抄读版本号 AFN:09 FN:1
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/BatchIssueVersion_09_1")]
        public async Task<BaseResultDto<BatchReadVersionOutput>> BatchReadVersion(BatchReadVersionInput input)
        {
            var result = new BaseResultDto<BatchReadVersionOutput>();
            foreach (var data in input.Data)
            {
                var address = $"{data.AreaCode}{data.Address}";
                var bytes = Build3761SendData.BuildTerminalVersionInfoReadingSendCmd(address);
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }
            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 查询采集日志 数据库
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Record/QueryRecordLog")]
        public Task<BaseResultDto<QueryRecordLogOutput>> QueryRecordLog(QueryRecordLogInput input)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 校准电表时间 透明转发
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("Handmould/MeterTiming_10_104")]
        public async Task<BaseResultDto> AdjustMeterTiming(AdjustMeterTimingInput input)
        {
            var result = new BaseResultDto();
            var address = $"{input.AreaCode}{input.Address}";

            var bytesList = new List<byte[]>();
            var dateDataUnit =
                Build645SendData.BuildAmmeterCorrectionTimeSendDataUnit(input.MeterAddress, input.Password,
                    "04 00 01 01", 0);
            var dateBytes = Build3761SendData.BuildTransparentForwardingSendCmd(address, input.Port, input.BaudRate.ToString(),
                dateDataUnit);
            bytesList.Add(dateBytes);

            var timeDataUnit =
                Build645SendData.BuildAmmeterCorrectionTimeSendDataUnit(input.MeterAddress, input.Password,
                    "04 00 01 02", 0);
            var timeBytes = Build3761SendData.BuildTransparentForwardingSendCmd(address, input.Port, input.BaudRate.ToString(),
                timeDataUnit);
            bytesList.Add(timeBytes);

            foreach (var bytes in bytesList)
            {
                //await _capBus.PublishAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                //{
                //    //ClientId = messageReceived.ClientId,
                //    DeviceNo = address,
                //    Message = bytes,
                //    Type = IssuedEventType.Data,
                //    MessageId = Guid.NewGuid().ToString()
                //});
                await _producerService.ProduceAsync(ProtocolConst.AmmeterSubscriberWorkerManualValveReadingIssuedEventName, new IssuedEventMessage
                {
                    //ClientId = messageReceived.ClientId,
                    DeviceNo = address,
                    Message = bytes,
                    Type = IssuedEventType.Data,
                    MessageId = Guid.NewGuid().ToString()
                });
            }

            result.Status = true;
            result.Msg = "操作成功";
            return result;
        }

        /// <summary>
        /// 更新集中器在线记录 数据库
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("AfterSaleApi/AddConrOnlineRecord")]
        public async Task<BaseResultDto> AddConrOnlineRecord(List<AddConrOnlineRecordInput> input)
        {
            var conrOnlineRecords = input.Select(it => new ConrOnlineRecord(it.AreaCode, it.Address, it.State, it.LastTime)).ToList();
            await _conrOnlineRecordRepository.InsertManyAsync(conrOnlineRecords);
            return new BaseResultDto()
            {
                Status = true
            };
        }

        /// <summary>
        /// 记录信号强度 数据库
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("AfterSaleApi/RssiToWebApi")]
        public async Task<BaseResultDto> AddSignalStrength(List<AddSignalStrengthInput> input)
        {
            var csqRecords = input.Select(it =>
                new CsqRecord(it.Address, it.AreaCode, it.DeviceType, it.Csq)).ToList();
            await _csqRecordRepository.InsertManyAsync(csqRecords);

            return new BaseResultDto()
            {
                Status = true
            };
        }

        /// <summary>
        /// 集中器上下线、心跳记录 数据库
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpPost("AfterSaleApi/AddFocusLog")]
        public async Task<BaseResultDto> AddFocusLog(List<AddFocusLogInput> input)
        {
            var focusLogs = input.Select(it =>
                new FocusRecord(it.Address, it.GatherServerId, int.Parse(it.IntervalTime), it.LogTime,
                    it.LogType, it.Remark)).ToList();
        
            await _focusRecordRepository.InsertManyAsync(focusLogs);

            return new BaseResultDto()
            {
                Status = true
            };
        }
    }
}
