using MECF.Framework.RT.EquipmentLibrary.Core.Extensions;
using MECF.Framework.RT.EquipmentLibrary.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway.Errors
{
    public class SunwayRobotAggregatedErrors : IBitTypeClass
    {
        #region Variables

        private const int BIT_WIDTH = 16;

        #endregion

        #region Constructors

        public SunwayRobotAggregatedErrors()
        {
            Input = new SunwayRobotInputErrors();
            Sensor = new SunwayRobotSensorErrors();
            AxisT = new SunwayRobotServoErrors();
            AxisR = new SunwayRobotServoErrors();
            AxisZ = new SunwayRobotServoErrors();
            Controller = new SunwayRobotControllerErrors();
        }

        public SunwayRobotAggregatedErrors(string response)
        {
            if (!IsErrResponse(response, out var rawErr))
                throw new InvalidOperationException("the format of response string is incorrect.");

            Input = int.TryParse(rawErr[0], NumberStyles.HexNumber, null, out var input)
                ? input.ToBitTypeClass<SunwayRobotInputErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotInputErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            Sensor = int.TryParse(rawErr[1], NumberStyles.HexNumber, null, out var sensor)
                ? sensor.ToBitTypeClass<SunwayRobotSensorErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotSensorErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            AxisT = int.TryParse(rawErr[2], NumberStyles.HexNumber, null, out var axisT)
                ? axisT.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            AxisR = int.TryParse(rawErr[3], NumberStyles.HexNumber, null, out var axisR)
                ? axisR.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            AxisZ = int.TryParse(rawErr[4], NumberStyles.HexNumber, null, out var axisZ)
                ? axisZ.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            AxisW = int.TryParse(rawErr[5], NumberStyles.HexNumber, null, out var axisW)
               ? axisW.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH)
               : 0xffff.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            AxisH = int.TryParse(rawErr[6], NumberStyles.HexNumber, null, out var axisH)
               ? axisH.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH)
               : 0xffff.ToBitTypeClass<SunwayRobotServoErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

            Controller = int.TryParse(rawErr[7], NumberStyles.HexNumber, null, out var cont)
                ? cont.ToBitTypeClass<SunwayRobotControllerErrors>(BIT_WIDTH)
                : 0xffff.ToBitTypeClass<SunwayRobotControllerErrors>(BIT_WIDTH); // 如果转换错误，全部置为错误，以防呆

        }

        #endregion

        #region Properties

        /// <summary>
        /// 输入错误
        /// </summary>
        public SunwayRobotInputErrors Input { get; }

        /// <summary>
        /// 传感器错误
        /// </summary>
        public SunwayRobotSensorErrors Sensor { get; }

        /// <summary>
        /// T轴错误
        /// </summary>
        public SunwayRobotServoErrors AxisT { get; }

        /// <summary>
        /// R轴错误
        /// </summary>
        public SunwayRobotServoErrors AxisR { get; }

        /// <summary>
        /// Z轴错误
        /// </summary>
        public SunwayRobotServoErrors AxisZ { get; }

        /// <summary>
        /// Z轴错误
        /// </summary>
        public SunwayRobotServoErrors AxisW { get; }

        /// <summary>
        /// Z轴错误
        /// </summary>
        public SunwayRobotServoErrors AxisH { get; }

        /// <summary>
        /// 控制器错误
        /// </summary>
        public SunwayRobotControllerErrors Controller { get; }

        /// <summary>
        /// 返回整合的错误信息列表。
        /// </summary>
        public List<string> AggregateErrorMessages
        {
            get
            {
                var errs = new List<string>();
                errs.AddRange(Input.AggregateErrorMessages());
                errs.AddRange(Sensor.AggregateErrorMessages());

                // 伺服轴的错误输出文本中加入轴名称
                errs.AddRange(AxisT.AggregateErrorMessages()
                    .Select(x => string.Concat($"[{nameof(AxisT)}]", x)));
                errs.AddRange(AxisR.AggregateErrorMessages()
                    .Select(x => string.Concat($"[{nameof(AxisR)}]", x)));
                errs.AddRange(AxisZ.AggregateErrorMessages()
                    .Select(x => string.Concat($"[{nameof(AxisZ)}]", x)));
                errs.AddRange(AxisW.AggregateErrorMessages()
                    .Select(x => string.Concat($"[{nameof(AxisW)}]", x)));
                errs.AddRange(AxisH.AggregateErrorMessages()
                    .Select(x => string.Concat($"[{nameof(AxisH)}]", x)));

                errs.AddRange(Controller.AggregateErrorMessages());

                return errs;
            }
        }

        #endregion

        #region Methods

        public static bool IsErrResponse(string response, out string[] errArray)
        {
            errArray = response.Split(',');
            return errArray.Length == 8;
        }

        #endregion
    }
}
