using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HTCoreServiceApp.Common;
using HTCoreServiceApp.Models;
using HTCoreServiceApp.Communicate.ModbusTcp;
using System.Collections;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Reflection;
using HTCoreServiceApp.Controllers;
using Opc.Ua;

namespace HTCoreServiceApp.DataHandle
{
    public class DataExtractOpc
    {
        public static async void  DataExtractCAsync(List<MetaTag> metaTags, string systenName, string groupName, string driverName, NodeId[] nodes, List<DataValue> values)
        {
            string res = await DataExtractConsecutive(metaTags, systenName, groupName, driverName, nodes, values);
        }
        public static Task <string> DataExtractConsecutive(List<MetaTag> metaTags, string systenName, string groupName, string driverName, NodeId[] nodes, List<DataValue> values)
        {
            return Task.Run(() =>
            {
                long hdatetime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
                List<MetaTagValue> listMetaTagValue = new List<MetaTagValue>();
                try
                {
                    //CodingTools.StartTime = DateTime.Now.Millisecond;//de
                    for (int i = 0; i < metaTags.Count; i++) 
                    {
                        MetaTag metaTag = metaTags[i];
                        short datatype = metaTag.DataType;
                        MetaTagValue metaTagValue = PCAutoCopy(metaTag);
                        switch (datatype)
                        {
                            case (short)DataType.FLOAT:
                                metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, i, values);
                                break;
                            case (short)DataType.BOOL:
                                metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, i, values);
                                break;
                            case (short)DataType.INT:
                                metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, i, values);
                                break;
                            case (short)DataType.WORD:
                                metaTagValue.TagValue = GetVlaue(datatype, metaTag.Address, i, values);
                                break;
                        }
                        listMetaTagValue.Add(metaTagValue);
                    }
                    //CodingTools.EndTime = DateTime.Now.Millisecond;//de
                    //var timess = (CodingTools.EndTime - CodingTools.StartTime).ToString();
                    //Console.WriteLine($"转换耗时：{timess}");
                    //Console.WriteLine(string.Join(",", (Array)listMetaTagValue.ToArray()) + "字节数据转换完成" + ",数据量：" + listMetaTagValue.Count.ToString());

                    //异步缓存
                    Task.Run(() => DataLiving.DataLive2CaChe(listMetaTagValue, driverName, groupName));

                    //异步储存
                    Task.Run(() => DataStorage.DataSave2DB(listMetaTagValue, systenName, driverName, groupName, hdatetime));

                    return "0";
                }
                catch (Exception ex)
                {
                    return "1";
                }
            });
        }

        /// <summary>
        /// 父类的value赋值给子类
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        private static MetaTagValue PCAutoCopy(MetaTag parent)
        {
            MetaTagValue child = new MetaTagValue();


            var ParentType = typeof(MetaTag);


            var Properties = ParentType.GetProperties();


            foreach (var Propertie in Properties)
            {
                if (Propertie.CanRead && Propertie.CanWrite)
                {
                    Propertie.SetValue(child, Propertie.GetValue(parent, null), null);
                }
            }


            return child;

            //listMetaTagValue.Add(new MetaTagValue()
            //{
            //    TagId = metaTag.TagId,

            //    TagName = metaTag.TagName,

            //    DataType = metaTag.DataType,

            //    DataSize = metaTag.DataSize,

            //    Address = metaTag.Address,

            //    GroupId = metaTag.GroupId,

            //    IsActive = metaTag.IsActive,

            //    Archive = metaTag.Archive,

            //    DefaultValue = metaTag.DefaultValue,

            //    Description = metaTag.Description,

            //    Maximum = metaTag.Maximum,

            //    Minimum = metaTag.Minimum,

            //    Cycle = metaTag.Cycle, 
            //});
        }

        private static string GetVlaue(short dataType, string address, int valueIndex, List<DataValue> values)
        {
            string val = "";

            
            switch (dataType)
            {
                case (short)DataType.FLOAT:
                    return values[valueIndex].ToString();
                case (short)DataType.BOOL:
                    return values[valueIndex].ToString();
                case (short)DataType.INT:
                    return values[valueIndex].ToString();
                //case (short)DataType.WORD:
                //    return ModbusClient.ConvertRegistersToInt(bytes, address_int).ToString();
            }
            return val;
        }
    }
}
