using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DotNettyFrom.common;
using DotNettyFrom.config;
using DotNettyFrom.db;
using DotNettyFrom.generatecmd;
using DotNettyFrom.model;
using DotNettyFrom.util;

namespace DotNettyFrom.generatecmd
{
    public class DtuCmdGenetor : CmdGenetor
    {
        //ID LEN
        private const int ID_LEN = 2;

        private const int FUNC_REPLY_READ = 16; //要回复的功能码
        private const int FUNC_REPLY_WRITE = 32; //要回复的功能码

        public override string GetLoginCmd(string ccid)
        {
            string cmd = DeviceId + "820014" + ccid;
            cmd = "7e7e7e" + CmdUtil.CalcCrcCode(cmd);
            return cmd;
        }

        public override string GetHeartbeat()
        {
            //7e7e7e00000000000184000085
            string cmd = DeviceId + "840000";
            cmd = "7e7e7e" + CmdUtil.CalcCrcCode(cmd);
            return cmd.ToUpper();
        }

        public override string GetReplyCmd(string receiveCmd)
        {
            int cmdId = GetCmdId(receiveCmd);
            Console.WriteLine("收到功能码=" + cmdId + " 16进制=" + Utils.tenToHex(cmdId));


            //跳过心跳包
            if (cmdId == SystemConfig.HeartbeatDownCmdCode)
            {
                if (SystemConfig.IsLogHeartBeatInfo)
                {
                    DataModel.ReceCollection.Add(new UIInfoModel("收到心跳", receiveCmd));
                }
                return null;
            }

            //处理其他的主动上报的回复


            //处理其他的主动上报的回复


            if (cmdId == int.MinValue)
            {
                DataModel.ReceCollection.Add(new UIInfoModel("帧错误", receiveCmd)
                    .setAction(-1)
                    .setSendType(SystemConfig.ReplyType));
                return null;
            }

            int position = SystemConfig.FunctionCodeStartPos * 2;
            //前面相同的, 到功能码前面
            string resp = receiveCmd.Substring(0, position);
            Console.WriteLine("前面回复相同的=" + resp);

            position += SystemConfig.FunctionCodeLength * 2;

            string frameDataLen = receiveCmd.Substring(position, SystemConfig.LengthFieldLength * 2);

            //帧中定义的数据长度.10进制的
            int frameDefineLen = Utils.hexToTen(frameDataLen);

            Console.WriteLine("数据长度= " + frameDataLen + "  -- 10进制=" + Utils.hexToTen(frameDataLen));

            position += SystemConfig.LengthFieldLength * 2;

            //测量点&消息流水-所占长度
            int msgFlowLength = SystemConfig.MeasurePointLen + SystemConfig.MessageFlowLen;

            //测量点&消息流水
            string msgFlow = receiveCmd.Substring(position, msgFlowLength * 2);
            position += msgFlowLength * 2;
            Console.WriteLine("测量点+消息流水=" + msgFlow);

            string codeIdHex = receiveCmd.Substring(position, ID_LEN * 2);
            int codeId = Utils.hexToTen(codeIdHex);
            //0301 这些写死,2位
            position += ID_LEN * 2;
            Console.WriteLine("功能码=" + codeIdHex + "; 10进制=" + Utils.hexToTen(codeIdHex));


            if (FUNC_REPLY_READ == cmdId)
            {
                DataModel.ReceCollection.Add(new UIInfoModel("收到读取", receiveCmd));

                //读,回复
                WvBean wb = DbHelper.GetInstance().SelectOneCmdByIndex(codeId);

                if (wb == null)
                {
                    DataModel.ReceCollection.Add(
                        new UIInfoModel(
                                "读取-字典中不存在这个功能码=" + codeId + " 16进制=" + codeIdHex,
                                receiveCmd)
                            .setAction(-1)
                            .setSendType(SystemConfig.ReplyType));
                    return null;
                }

                string ud = wb.userValue;
                Console.WriteLine(ud);
                string lenMsgFlowData = ReadMessage(wb, msgFlow, codeIdHex);

                int replyCmdId = cmdId + 128;
                resp += CmdUtil.FrontWithZero(Utils.tenToHex(replyCmdId), SystemConfig.FunctionCodeLength * 2);
                resp += lenMsgFlowData;
                resp += CmdUtil.CalcCrcCodeSkip(resp, 3);

                DataModel.ReceCollection.Add(
                    new UIInfoModel("读取成功,回复", resp)
                        .setAction(-1)
                        .setSendType(SystemConfig.ReplyType));

                return resp;
            }
            else if (FUNC_REPLY_WRITE == cmdId)
            {
                DataModel.ReceCollection.Add(new UIInfoModel("收到设置", receiveCmd));

                //写
                WvBean wb = DbHelper.GetInstance().SelectOneCmdByIndex(codeId);

                if (wb == null)
                {
                    DataModel.ReceCollection.Add(
                        new UIInfoModel(
                                "设置-字典中不存在这个功能码=" + codeId + " 16进制=" + codeIdHex,
                                receiveCmd)
                            .setAction(-1)
                            .setSendType(SystemConfig.ReplyType));
                    return null;
                }

                //取出设置数据
                Console.WriteLine("长度   " + (frameDefineLen - msgFlowLength - ID_LEN));
                string setData = receiveCmd.Substring(position, 2 * (frameDefineLen - msgFlowLength - ID_LEN));

                wb.userValue = setData;

                string resultData = "";
                string tip = "";
                int result = DbHelper.GetInstance().UpdateCmd(wb);
                if (result > 0)
                {
                    resultData = "00";
                    tip = "设置成功,回复";
                }
                else
                {
                    resultData = "01";
                    tip = "设置失败,回复";
                }


//                7E7E7E000000000001a000a1

                int replyCmdId = cmdId + 128;
                resp += CmdUtil.FrontWithZero(Utils.tenToHex(replyCmdId), SystemConfig.FunctionCodeLength * 2); //功能码

                string replyData = msgFlow + codeIdHex + resultData;
                if (replyData.Length % 2 != 0)
                {
                    replyData += "0";
                }
                //长度
                string lenHex =
                    CmdUtil.FrontWithZero(Utils.tenToHex(replyData.Length / 2), SystemConfig.LengthFieldLength * 2);
                resp += lenHex;
                resp += replyData; //消息体
                resp += CmdUtil.CalcCrcCodeSkip(resp, 3);
                DataModel.ReceCollection.Add(
                    new UIInfoModel(tip + " set(" + codeIdHex + ")=value(" + setData + ")", resp)
                        .setAction(-1)
                        .setSendType(SystemConfig.ReplyType));

                return resp;
            }


//            LengthAdjustment
//            string codeData = receiveCmd.Substring(position, receiveCmd.Length - SystemConfig.LengthAdjustment * 2);
//            Console.WriteLine("收到数量=" + codeData);

            //处理主动上报的回复&心跳.那些不用回复

            //处理主动上报的回复&心跳.那些不用回复


//            WvBean wb = DbHelper.GetInstance().SelectOneCmdById(cmdId);
//            Console.WriteLine(wb);

            DataModel.ReceCollection.Add(new UIInfoModel("收到", receiveCmd));


            return null;
        }

        private string ReadMessage(WvBean wb, string msgFlow, string codeIdHex)
        {
            string content = msgFlow + codeIdHex + wb.userValue.Trim();
            if (content.Length % 2 != 0)
            {
                content = "0" + content;
            }

            string lenHex =
                CmdUtil.FrontWithZero(Utils.tenToHex(content.Length / 2), SystemConfig.LengthFieldLength * 2);

            return lenHex + content;
        }
    }
}