using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MesAdaptor
{
    public class SajectConnectSajet
    {
        public enum CMD
        {
            Signin = 1,
            SnCheck = 2,
            WoCheck = 14,
            Report = 3,
            Log = 4,
            HeaderRegister = 8,
            ValueReport = 5,
            StringValueReport = 6,
        }

        public static bool SajetTransStart() => SajetConnectAdapter.SajetTransStart();
        public static bool SajetTransClose() => SajetConnectAdapter.SajetTransClose();

        private static string userId = "";
        public static bool SajetTransSignIn(ref string data)
        {
            var attemptId = data;
            if (SajetTransData(CMD.Signin, ref data))
            {
                if (string.IsNullOrEmpty(data) || data.StartsWith("NG"))
                {
                    userId = "";
                    return false;
                }
                else
                {
                    userId = attemptId;
                    return true;
                }
            }
            userId = "";
            return false;
        }

        private static string WorkOrder = "";
        public static bool SajetTransWoCheck(ref string workOrder)
        {
            if (string.IsNullOrEmpty(userId))
                return false;
            if (workOrder == null)
                workOrder = "";
            var msg = userId + ";" + workOrder;

            if (SajetTransData(CMD.WoCheck, ref msg))
            {
                if (string.IsNullOrEmpty(msg) || msg.StartsWith("NG"))
                {
                    WorkOrder = "";
                    return false;
                }
                else
                {
                    WorkOrder = workOrder;
                    return true;
                }
            }
            WorkOrder = "";
            return false;
        }

        private static string SN;
        public static bool SajetTransSnCheck(ref string serialNumber)
        {
            var attemptSN = serialNumber;
            var msg = serialNumber;

            if (SajetTransData(CMD.SnCheck, ref msg))
            {
                if (string.IsNullOrEmpty(msg) || msg.StartsWith("NG"))
                {
                    SN = "";
                    return false;
                }
                else
                {
                    SN = attemptSN;
                    return true;
                }
            }
            SN = "";
            return false;
        }

        public static bool SajetTranFinishSuccess()
        {
            if (string.IsNullOrEmpty(userId))
                return false;
            if (string.IsNullOrEmpty(SN))
                return false;
            string msg = userId + ";" + SN + ";";

            if (string.IsNullOrEmpty(msg))
                return false;

            msg += "OK";

            return SajetTransData(CMD.Report, ref msg);
        }

        public static bool SajetTranFinishFail(string errorCode)
        {
            if (string.IsNullOrEmpty(userId))
                return false;
            if (string.IsNullOrEmpty(SN))
                return false;
            string msg = userId + ";" + SN + ";";

            if (string.IsNullOrEmpty(msg))
                return false;

            msg += $"NG;{errorCode};";

            return SajetTransData(CMD.Report, ref msg);
        }

        public static string SajetTransRegisterHeader(string model, string header)
        {
            if (string.IsNullOrEmpty(userId))
                return "";
            var msg = userId + ";";
            msg += model + ";" + header;
            if (SajetTransData(CMD.HeaderRegister, ref msg))
            {
                if (msg.StartsWith("OK"))
                {
                    //get codename
                    msg = msg.Substring(3);
                    var spaceIndex = msg.IndexOf(";");
                    if (spaceIndex > 0)
                    {
                        msg = msg.Substring(0, spaceIndex);
                    }
                    return msg;
                }
                return null;
            }
            return null;
        }

        public static bool SajetTransReport(Dictionary<string, string> reportPair)
        {
            //build header
            Dictionary<string, int> valuePairs = new Dictionary<string, int>();
            foreach (var pair in reportPair)
            {
                if (int.TryParse(pair.Value, out int val))
                {
                    valuePairs.Add(pair.Key, val);
                }
                else if (pair.Value.ToLower().Contains("fail"))
                {
                    valuePairs.Add(pair.Key, 0);
                }
                else if (pair.Value.ToLower().Contains("success"))
                {
                    valuePairs.Add(pair.Key, 1);
                }
                else
                {
                    valuePairs.Add(string.Format("{0}:{1}", pair.Key, pair.Value), 1);
                }
            }
            //register Header
            var codePair = new Dictionary<string, string>();

            string model = "";
            if (PhihongSystemID.SystemID.TryParse(SN,out var systemID))
            {
                model = systemID.ModelName.ToString();
            }

            foreach (var key in valuePairs.Keys)
            {
                var code = SajectConnectSajet.SajetTransRegisterHeader(model, key);
                if (string.IsNullOrEmpty(code))
                    continue;
                codePair.Add(key, code);
            }
            //report value
            var reportResult = SajectConnectSajet.SajetTransReport(valuePairs, codePair);
            return reportResult;
        }

        public static bool SajetTransReport(Dictionary<string, int> resultPair, Dictionary<string, string> codePair)
        {
            if (string.IsNullOrEmpty(userId))
                return false;
            if (string.IsNullOrEmpty(SN))
                return false;
            string msgHeader = userId + ";" + SN;
            string msg = "";

            foreach (var result in resultPair)
            {
                if (codePair.Keys.Contains(result.Key))
                {
                    msg = string.Format("{0};{1}:{2};",msgHeader, codePair[result.Key], string.Format("{0}.00", result.Value));
                    //msg += string.Format(";{0}:{1}", codePair[result.Key], string.Format("{0}.00", result.Value));
                }
                //msg += ";";
                SajetTransData(CMD.ValueReport, ref msg);
                //msg = userId + ";" + SN;
            }
            //msg += ";";
            return true;
        }

        public static bool SajetTransReport(Dictionary<string, string> resultPair, Dictionary<string, string> codePair)
        {
            if (string.IsNullOrEmpty(userId))
                return false;
            if (string.IsNullOrEmpty(SN))
                return false;
            string msg = userId + ";" + SN;
            foreach (var result in resultPair)
            {
                if (codePair.Keys.Contains(result.Key))
                {
                    msg += string.Format(";{0}:{1}", codePair[result.Key], string.Format("{0}.00", result.Value));
                }
                msg += ";";
                SajetTransData(CMD.StringValueReport, ref msg);
                msg = userId + ";" + SN;
            }
            msg += ";";
            return true;
        }

        public static bool SajetTransLog(string data)
        {
            return true;

            if (string.IsNullOrEmpty(userId))
                return false;
            if (string.IsNullOrEmpty(SN))
                return false;
            string prefix = userId + ";" + SN + ";";
            while (data.Length > 0)
            {
                var msg = prefix;
                int sendLength = Math.Min(250 - msg.Length, data.Length);
                var sendString = data.Substring(0, sendLength);
                msg += sendString;
                if (!SajetTransData(CMD.Log, ref msg))
                {
                    break;
                }
                data = data.Substring(sendLength);
            }
            return data.Length == 0;
        }

        private static bool SajetTransData(CMD command, ref string data)
        {
            return SajetConnectAdapter.SajetTransData((int)command, ref data);
        }

        private static string GetSendPrefix()
        {
            string msg = "";
            if (string.IsNullOrEmpty(userId))
            {
                return null;
            }
            msg = userId + ";";
            if (string.IsNullOrEmpty(WorkOrder))
            {
                return null;
            }
            msg += WorkOrder + ";";
            return msg;
        }
    }
}