using Aitex.Common.Util;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using FurnaceRT.Equipments.PMs.Devices;
using FurnaceRT.Instances;
using HslCommunication.Profinet.Panasonic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace FurnaceRT.Extraction
{
    /// 
    /// RT模块中重复方法抽离
    /// 
    public class ExtractionMethods
    {
        public static string systemSCFile = PathManager.GetCfgDir() + $"System.sccfg";
        public static Dictionary> AllNameKeyDict = new Dictionary>();
        public static Dictionary RecipeExecIoValve = new Dictionary() { };
        public static Dictionary RecipeExecIoMFC = new Dictionary() { };
        /// 
        /// 解析DeviceModelDefine文件 指定类型节点下的ids
        /// 
        /// 
        public static Dictionary> GetNameKeyDict(List typeNames)
        {
            Dictionary> result = new Dictionary>();
            foreach (string name in typeNames)
            {
                if (result.ContainsKey(name)) continue;
                result.Add(name, new List());
            }
            GetXmlElement($"{SC.GetStringValue("System.SetUp.ToolType")}\\DeviceModelPM", result);
            GetXmlElement("DeviceModelHeater", result, true);
            GetXmlElement($"{SC.GetStringValue("System.SetUp.ToolType")}\\DeviceModelGasLine", result);
            return result;
        }
        public static void GetXmlElement(string fileName, Dictionary> result, bool isSystem = false)
        {
            XmlDocument xmlDoc = new XmlDocument();
            var cfDirPath = PathManager.GetCfgDir();
            var path = cfDirPath + $"IO\\{fileName}.xml";
            if (!File.Exists(path)) return;
            xmlDoc.Load(path);
            XmlNode node = xmlDoc.SelectSingleNode("DeviceModelDefine");
            foreach (XmlNode item in node.ChildNodes)
            {
                if (item.NodeType != XmlNodeType.Element) continue;
                var element = item as XmlElement;
                var classType = element.GetAttribute("classType");
                if (classType == null) continue;
                classType = classType.Split('.').LastOrDefault();
                if (!result.Keys.Contains(classType)) continue;
                foreach (XmlNode children in item.ChildNodes)
                {
                    if (children is XmlElement childElement)
                    {
                        if (result[classType].Contains(childElement.GetAttribute("id"))) continue;
                        var key = isSystem ? $"System.{childElement.GetAttribute("id")}.DeviceData" : $"PM1.{childElement.GetAttribute("id")}.DeviceData";
                        result[classType].Add(key);
                    }
                }
            }
        }
        public static void InitRecipeIoValve()
        {
            XmlDocument xmlDoc = new XmlDocument();
            var cfDirPath = PathManager.GetCfgDir();
            var path = cfDirPath + $"GasXml\\GasViewXml.xml";
            if (!File.Exists(path))
            {
                return;
            }
            xmlDoc.Load(path);
            XmlNodeList boolConditions = xmlDoc.SelectNodes("//BoolCondition");
            if (boolConditions == null)
                return;
            foreach (XmlNode condition in boolConditions)
            {
                if (string.IsNullOrEmpty(condition.InnerText) || !condition.InnerText.Contains("Valve") || condition.InnerText.Contains("ILKValue"))
                    continue;
                var cleanedString = new string(condition.InnerText.Where(c => !char.IsWhiteSpace(c)).ToArray());
                var valveName = cleanedString.Replace("return", "").Trim().Split('.')[1];
                if (RecipeExecIoValve.ContainsKey(valveName))
                    continue;
                IDevice device = DEVICE.GetDevice($"PM1.{valveName}");
                if (device == null)
                    continue;
                RecipeExecIoValve.Add(valveName, device as IoValve);
            }
        }
        public static void InitRecipeIoMFC()
        {
            XmlDocument xmlDoc = new XmlDocument();
            var cfDirPath = PathManager.GetCfgDir();
            var path = cfDirPath + $"GasXml\\GasViewXml.xml";
            if (!File.Exists(path))
            {
                return;
            }
            XDocument doc = XDocument.Load(path);
            // 查找Analogs节点下的所有Analog节点
            var analogs = doc.Descendants("Analog");
            foreach (var analog in analogs)
            {
                // 检查Analog节点的Enable属性是否为True
                if (analog.Attribute("Enable")?.Value == "True")
                {
                    var topButton = analog.Element("TopButton");
                    if (topButton != null)
                    {
                        var innerText = topButton.Element("InnerText");
                        if (innerText != null)
                        {
                            string textContent = innerText.Attribute("Text")?.Value;
                            var mfcName = $"MFC{textContent}";
                            if (RecipeExecIoMFC.ContainsKey(mfcName))
                            {
                                continue;
                            }
                            IDevice device = DEVICE.GetDevice($"PM1.{mfcName}");
                            if (device == null)
                                continue;
                            RecipeExecIoMFC.Add(mfcName, device as IoMFC);
                        }
                    }
                }
            }
        }
        /// 
        /// 根据xml配置获取N2PurgeSequenceAction配置
        /// 
        /// 
        public static Dictionary>>> GetN2PurgeSequenceAction()
        {
            Dictionary>>> result = new Dictionary>>>();
            XDocument doc = XDocument.Load(ExtractionMethods.systemSCFile);
            var pmNode = doc.Root.Elements("configs")
                .Where(x => (string)x.Attribute("name") == "PM1")
                .FirstOrDefault();
            var nameGroup = pmNode.Elements("configs")
                .Where(x => (string)x.Attribute("name") == "N2Purge")
                .FirstOrDefault()
                .Elements("configs")
                .GroupBy(a => (string)a.Attribute("name"));
            var pM1N2PurgeNodeChildren = nameGroup.ToDictionary(a => a.Key, a => a.ToList().FirstOrDefault());
            foreach (var xmlItem in pM1N2PurgeNodeChildren)
            {
                var configElements = xmlItem.Value.Elements("config").ToList();
                var resultItem = new List>();
                foreach (var valveConfig in configElements)
                {
                    if (valveConfig != null &&
                        valveConfig.Attribute("name") != null &&
                        valveConfig.Attribute("default") != null)
                    {
                        string name = (string)valveConfig.Attribute("name");
                        var defaultValue = (string)valveConfig.Attribute("default");
                        var deviceItem = DEVICE.GetDevice($"PM1.{name}");
                        if (deviceItem == null)
                            continue;
                        var item = Tuple.Create(deviceItem, defaultValue);
                        resultItem.Add(item);
                    }
                }
                result.Add(xmlItem.Key, Tuple.Create(new R_TRIG(), resultItem));
            }
            return result;
        }
    }
}