using HTCoreServiceApp.Common;
using HTCoreServiceApp.DataHandle;
using HTCoreServiceApp.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
//using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;

namespace HTCoreServiceApp.WebApi
{
	//[ApiController]
	//[Route("[controller]/[action]")]
	public class DeviceControl // : ControllerBase
	{
		private readonly DriverService _driverService;
		private readonly List<MetaGroup> metaGroups;
		private readonly List<MetaDriver> metaDrivers;
		private readonly List<MetaTag> metaTags;
		public DeviceControl(DriverService driverService)
		{
			_driverService = driverService;
			//string ConnectionStrings = AESKeyEncrypt.DecryptDES(ConfigHelper.ReadAppSettings("ConnectionStrings", "SqlServer"));
			var db = new SqlSugarClient(StaticLibrary.DBConfig);
			metaGroups = db.Queryable<MetaGroup>().ToList(); //db.MetaGroups.ToList();
			metaDrivers = db.Queryable<MetaDriver>().ToList(); //db.MetaDrivers.ToList();
			metaTags = db.Queryable<MetaTag>().ToList(); //db.MetaTags.ToList();
			db.Dispose();
		}
		//[HttpGet]
		public async Task<string> Get()  //请求方法行为
		{
			return "hello，这里是恒拓设备实时控制服务！";
		}
		//[HttpGet]
		public async Task<string> GetName(string Name)  //请求方法行为
		{
			return $"服务器收到字符串：{Name}";
		}
		//[HttpGet]
		public async Task<string> SetDeviceData(string groupName,string tagName,string value)
		{
            //var t1 = DateTime.Now;
            //var ip = HttpContext.GetClientUserIp();
            //var cache = StaticLibrary.MemoryCacheHelper.Get<List<LiveGroupDictionary>>(driverName).Where(x=>x.GroupName == groupName).First();
            //var val = new List<LiveGroupDictionary>();
            //StaticLibrary.MemoryCacheHelper.TryGetValue(driverName,out val);
            //return LiveJsonIntegrate.MetaValues2Json(val.FirstOrDefault());

            //var userAgent = HttpContext.

            int reCode = 0;

			//直接返回，取消后续写入步骤
			//return reCode;
			try
			{
				if (!string.IsNullOrEmpty(groupName) && !string.IsNullOrEmpty(tagName) && !string.IsNullOrEmpty(value))
				{
					//var context = StaticLibrary.DBContext;
					//return StaticLibrary.MemoryCacheHelper.GetString(groupName);
					var driverID = metaGroups.Where(x => x.GroupName == groupName).FirstOrDefault().DriverId;
					var driverName = metaDrivers.Where(x => x.DriverId == driverID).FirstOrDefault().DriverName;
					var groupID = metaGroups.Where(x => x.GroupName == groupName).FirstOrDefault().GroupId;
					var dataType = metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().DataType;
					var writeAddress = metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().WriteAddress;//231113 ,CDL QWZ 写入地址字段由WriteAddress修改为PLCAddress
					if(writeAddress == ""|| writeAddress == null)
					{
						reCode = 3;
						return reCode.ToString();
					}
                    //var windex = writeAddress.IndexOf(".");
                    //writeAddress = writeAddress.Remove(windex, 1).Insert(windex, ",");
                    //var valueHandle = 0;
                    if (dataType == (short)DataType.BOOL)
					{
						if (value.Equals("True") || value.Equals("true") || value.Equals("TRUE") || value.Equals("1"))
						{
							value = "1";
						}
						else if (value.Equals("False") || value.Equals("false") || value.Equals("FALSE") || value.Equals("0"))
						{
							value = "0";
						}
					}
					if (dataType == (short)DataType.IFLOAT)
					{
                        var iFloatPlaces = (int)metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().IFloatPlaces;
						value = ((int)(float.Parse(value) * (int)Math.Pow(10.0f, iFloatPlaces))).ToString();
                    }
                    var writePara = new WritePara
                    {
						TagName = tagName,
						GroupName = groupName,
						WriteAddress = writeAddress,
						DataType = dataType,
						Value = value
					};
                    //string serJson = JsonSerializer.Serialize(writePara); //JsonConvert.SerializeObject(writePara);

                    //var t2 = DateTime.Now;
                    //var timediff = t2 - t1;
                    //Console.WriteLine($"写入参数初始化耗时：{timediff}");

                    foreach (var driverThread in _driverService.DriverThreads)
					{
						if (driverThread.driverName == driverName)
						{
							reCode = driverThread.DriverWrite(writePara);
						}
					}
				}
				else
				{
					reCode = 2;
				}
			}
			catch (Exception ex)
			{
                reCode = 1;
                GC.Collect();
                LogHelper.LogWrite("S7写入数据出错，TagName：" + tagName.ToString() + ",ERROR：" + ex.ToString());
                return reCode.ToString() + "/t" + ex.ToString();
            }
			GC.Collect();
			return reCode.ToString();
		}
        public async Task<string> SetDeviceTagData(string tagName,string value,HttpContext context)
		{
			var htsetlog = new HTLogSetDriver();
			htsetlog.EventTime = DateTime.Now;
			//var t1 = DateTime.Now;
			htsetlog.RequestIp = context.Connection.RemoteIpAddress.ToString();// "192.168.110.247";
			//var cache = StaticLibrary.MemoryCacheHelper.Get<List<LiveGroupDictionary>>(driverName).Where(x=>x.GroupName == groupName).First();
			//var val = new List<LiveGroupDictionary>();
			//StaticLibrary.MemoryCacheHelper.TryGetValue(driverName,out val);
			//return LiveJsonIntegrate.MetaValues2Json(val.FirstOrDefault());

			//var userAgent = HttpContext.

			int reCode = 0;
			//直接返回，取消后续写入步骤
			//return reCode;
			try
			{
				if (!string.IsNullOrEmpty(tagName) && !string.IsNullOrEmpty(value))
				{
					//var context = StaticLibrary.DBContext;
					//return StaticLibrary.MemoryCacheHelper.GetString(groupName);
					//var dataType = metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().DataType;
					//var writeAddress = metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().PLCAddress;//231113 ,CDL QWZ 写入地址字段由WriteAddress修改为PLCAddress
					var tag = metaTags.Where(x => x.TagName == tagName).First();
                    var dataType = tag.DataType;
                    var groupID = tag.GroupId;
                    var driverID = metaGroups.Where(x => x.GroupId == groupID).FirstOrDefault().DriverId;
                    var driverName = metaDrivers.Where(x => x.DriverId == driverID).FirstOrDefault().DriverName;
                    var writeAddress = tag.WriteAddress;//231113 ,CDL QWZ 写入地址字段由WriteAddress修改为PLCAddress
					htsetlog.WriteDriverName = driverName;
					htsetlog.WriteTagName = tag.TagName;
					htsetlog.WriteAddress = writeAddress;
					htsetlog.WriteValue = value;

                    if (writeAddress == ""|| writeAddress == null)
					{
						reCode = 3;
						htsetlog.WriteResult = reCode.ToString();
						LogHelper.SetDriverLogTask(htsetlog);
						return reCode.ToString();
					}
                    //var windex = writeAddress.IndexOf(".");
                    //writeAddress = writeAddress.Remove(windex, 1).Insert(windex, ",");
                    //var valueHandle = 0;
                    if (dataType == (short)DataType.BOOL)
					{
						if (value.Equals("True") || value.Equals("true") || value.Equals("TRUE") || value.Equals("1"))
						{
							value = "1";
						}
						else if (value.Equals("False") || value.Equals("false") || value.Equals("FALSE") || value.Equals("0"))
						{
							value = "0";
						}
					}
					if (dataType == (short)DataType.IFLOAT)
					{
                        var iFloatPlaces = (int)tag.IFloatPlaces;
						value = ((int)(float.Parse(value) * (int)Math.Pow(10.0f, iFloatPlaces))).ToString();
                    }
                    var writePara = new WritePara
                    {
						TagName = tagName,
						//GroupName = groupName,
						WriteAddress = writeAddress,
						DataType = dataType,
						Value = value
					};
                    //string serJson = JsonSerializer.Serialize(writePara); //JsonConvert.SerializeObject(writePara);

                    //var t2 = DateTime.Now;
                    //var timediff = t2 - t1;
                    //Console.WriteLine($"写入参数初始化耗时：{timediff}");

                    foreach (var driverThread in _driverService.DriverThreads)
					{
						if (driverThread.driverName == driverName)
						{
							reCode = driverThread.DriverWrite(writePara);
							htsetlog.WriteResult = reCode.ToString();
						}
					}
				}
				else
				{
					reCode = 2;
					htsetlog.WriteResult = reCode.ToString();
				}
			}
			catch (Exception ex)
			{
				reCode = 1;
				htsetlog.WriteResult = reCode.ToString();
				htsetlog.WriteErrInformation = ex.ToString();
				
				LogHelper.SetDriverLogTask(htsetlog);
				
				GC.Collect();
                LogHelper.LogWrite("S7写入数据出错，TagName：" + tagName.ToString() + ",ERROR：" + ex.ToString());
                return reCode.ToString()+ "/t" + ex.ToString();
            }
			LogHelper.SetDriverLogTask(htsetlog);
			GC.Collect();
			return reCode.ToString();
		}

        public async Task<string> SetDeviceBlockData(string driverName, string address, string value)
        {
            

            int reCode = 0;

            try
            {
                if (!string.IsNullOrEmpty(driverName) && !string.IsNullOrEmpty(address) && !string.IsNullOrEmpty(value))
                {
                    //var context = StaticLibrary.DBContext;
                    //return StaticLibrary.MemoryCacheHelper.GetString(groupName);
                   
                    
                    var writeAddress = address;//231113 ,CDL QWZ 写入地址字段由WriteAddress修改为PLCAddress
                    if (writeAddress == "" || writeAddress == null)
                    {
                        reCode = 3;
                        return reCode.ToString();
                    }
                    //var windex = writeAddress.IndexOf(".");
                    //writeAddress = writeAddress.Remove(windex, 1).Insert(windex, ",");
                    bool isBool = false;
                    bool isNumber = false;
                    var dataType = (byte)DataType.BOOL; 
                    if (bool.TryParse(value, out bool boolValue))
                    {
                        isBool = true;
                        dataType = (byte)DataType.BOOL;
                    }

                    // 检查是否为数字
                    if (double.TryParse(value, out double numberValue))
                    {
                        isNumber = true;
                        dataType = (byte)DataType.FLOAT;
                    }

                    // 如果都不是，输出结果
                    if (!isBool && !isNumber)
                    {
                        reCode = 8;
                        return reCode.ToString();
                    }

                    
                    //var valueHandle = 0;
                    if (isBool)
                    {
                        if (value.Equals("True") || value.Equals("true") || value.Equals("TRUE") || value.Equals("1"))
                        {
                            value = "1";
                        }
                        else if (value.Equals("False") || value.Equals("false") || value.Equals("FALSE") || value.Equals("0"))
                        {
                            value = "0";
                        }
                    }
                    else if (isNumber)
                    {
                        //var iFloatPlaces = (int)metaTags.Where(x => x.TagName == tagName && x.GroupId == groupID).First().IFloatPlaces;
                        value = float.Parse(value).ToString();
                    }
                    var writePara = new WriteBlockPara
                    {
                        WriteAddress = writeAddress,
                        DataType = dataType,
                        Value = value
                    };
                    //string serJson = JsonSerializer.Serialize(writePara); //JsonConvert.SerializeObject(writePara);

                    //var t2 = DateTime.Now;
                    //var timediff = t2 - t1;
                    //Console.WriteLine($"写入参数初始化耗时：{timediff}");

                    foreach (var driverThread in _driverService.DriverThreads)
                    {
                        if (driverThread.driverName == driverName)
                        {
                            reCode = driverThread.DriverBlockWrite(writePara);
                        }
                    }
                }
                else
                {
                    reCode = 2;
                }
            }
            catch (Exception ex)
            {
                reCode = 1;
                GC.Collect();
                return reCode.ToString() + "/t" + ex.ToString();
            }
            GC.Collect();
            return reCode.ToString();
        }
    }
}
