using Aitex.Core.RT.Log;
using DocumentFormat.OpenXml.InkML;
using MECF.Framework.Common.Aitex.Core.Common.DeviceData;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.Equipment;
using Sicentury.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;

namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
{
    public class ProcessHistorySqlHelp
    {
        public static List<RecipeProcessHistoryData> QueryRecipeProcessHistoryData(string starTime, string endTime, string pm)
        {
            string cmd = $"select * from process_data where process_in='{pm}' and process_status='Succeed' and process_begin_time between '{starTime}' and '{endTime}' order by process_begin_time desc";
            return GetPMCoatingList(cmd);
        }


        //**********************************************时间区间内Recipe运行记录查询*************************************************************
        private static List<RecipeProcessHistoryData> GetPMCoatingList(string cmd)
        {
            List<RecipeProcessHistoryData> recipeProcessHistoryDataList = new List<RecipeProcessHistoryData>();
            try
            {
                var dt = QueryDataClient.Instance.Service.QueryData(cmd);//只能界面用
                if (dt == null || dt.Rows.Count == 0)
                    return null;

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    RecipeProcessHistoryData recipeProcessHistoryData = new RecipeProcessHistoryData()
                    {
                        PmModel = dt.Rows[i]["process_in"].ToString(),
                        XPath = dt.Rows[i]["recipe_name"].ToString(),
                        Status = dt.Rows[i]["process_status"].ToString(),
                        ProcessGuid = dt.Rows[i]["guid"].ToString(),
                        BeginTime = dt.Rows[i]["process_begin_time"].ToString(),
                        EndTime = dt.Rows[i]["process_end_time"].ToString(),
                        WaferDataGuid = dt.Rows[i]["wafer_data_guid"].ToString()
                    };
                    GetWaferInf(recipeProcessHistoryData);
                    recipeProcessHistoryDataList.Add(recipeProcessHistoryData);
                }
            }
            catch (Exception)
            {
                return null;
            }
            return recipeProcessHistoryDataList;
        }

        private static void GetWaferInf(RecipeProcessHistoryData recipeProcessHistoryData)
        {
            string cmd = $"select * from wafer_data where wafer_id='{recipeProcessHistoryData.WaferDataGuid}' ";
            var dt = QueryDataClient.Instance.Service.QueryData(cmd);
            if (dt == null || dt.Rows.Count == 0)
                return;
            recipeProcessHistoryData.WaferInf = $"{dt.Rows[0]["create_station"]}_{dt.Rows[0]["create_slot"]}";
            recipeProcessHistoryData.TrayInf = $"{dt.Rows[0]["create_station"]}_{dt.Rows[0]["create_slot"]}";
        }

        //**********************************************选中Recipe时，查询当时记录的总的步骤流程*************************************************
        public static ObservableCollection<ProcessHistoryData> QueryProcessHistoryData(string processGuid, string recipeName,string stepModel)
        {
            string cmd = $"select * from recipe_step_data where process_data_guid='{processGuid}' order by step_begin_time asc ";
            return GetProcessHistoryDataList(cmd, recipeName, stepModel);
        }

        private static ObservableCollection<ProcessHistoryData> GetProcessHistoryDataList(string cmd, string recipeName, string stepModel)
        {
            ObservableCollection<ProcessHistoryData> processHistoryDataList = new ObservableCollection<ProcessHistoryData>();
            try
            {
                var dt = QueryDataClient.Instance.Service.QueryData(cmd);
                if (dt == null || dt.Rows.Count == 0)
                    return null;

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    ProcessHistoryData recipeProcessHistoryData = new ProcessHistoryData()
                    {
                        StepBeginTime = dt.Rows[i]["step_begin_time"].ToString(),
                        StepEndTime = dt.Rows[i]["step_end_time"].ToString(),
                        RecipeName = recipeName,
                        StepName = dt.Rows[i]["step_name"].ToString(),
                        StepTime = dt.Rows[i]["step_time"].ToString(),
                        StepNumber = dt.Rows[i]["step_number"].ToString()
                    };

                    if (stepModel=="All")//All返回所有，*筛选出步骤名称中带有*
                        processHistoryDataList.Add(recipeProcessHistoryData);
                    else if (stepModel=="*")
                        if (recipeProcessHistoryData.StepName.Contains("*"))
                            processHistoryDataList.Add(recipeProcessHistoryData);
                }
            }
            catch (Exception)
            {
                return null;
            }
            return processHistoryDataList;
        }

        


        //************************************************单步时硬件数据结果查询*******************************************************************

        /// <summary>
        /// 拆分的天循查询数据
        /// </summary>
        /// <param name="daySlices">拆分的天</param>
        /// <param name="moduleName">PM名称</param>
        /// <param name="gasFlowSumList">显示列表对象</param>
        /// <returns></returns>
        public static ObservableCollection<ProcessHistoryDeviceData> GetProcessHistoryDeviceData(IEnumerable<DateRangeHelper> daySlices, string moduleName, List<ProcessDeviceItem> processHistoryItemList)
        {
            List<DataTable> dataTableList =new List<DataTable>();

            foreach (var daySlice in daySlices)//拆分天
            {
                var dt = GetProcessHistoryDeviceDataListDaySlices(daySlice, moduleName, processHistoryItemList);
                if (dt != null)
                    dataTableList.Add(dt);//拆分后，每次查询结果放入集合中
            }


            ObservableCollection<ProcessHistoryDeviceData> processHistoryDeviceDataList = new ObservableCollection<ProcessHistoryDeviceData>();

            foreach (var item in processHistoryItemList)
            {
                var phd = new ProcessHistoryDeviceData();
                phd.DeviceName = item.Display;
                phd.DATASubscribeName = item.Property;
                phd.Unit = item.Unit;
                phd.IsPropertyExists = item.IsPropertyExists;
                foreach (DataTable ds in dataTableList)
                {
                    for (int i = 0; i < ds.Rows.Count; i++)
                    {
                        if (!item.IsPropertyExists)
                            continue;
                        string value = ds.Rows[i][$"{moduleName}.{item.Property}"].ToString();
                        if (value is not null && value.Length == 0)
                            continue;
                        float cache;
                        if (float.TryParse(value, out cache))//防止非数据类型混入进来
                        {
                            phd.DeviceValue.Add(cache);//历史数据点
                            phd.TimeStamp.Add(ds.Rows[i]["time"].ToString());//时间戳
                        }
                    }
                }

                if (phd.IsPropertyExists)
                {
                    phd.CalculateData();
                    processHistoryDeviceDataList.Add(phd);
                }
                
            }
            return processHistoryDeviceDataList;
        }

        /// <summary>
        /// 根据拆分的天循查询数据
        /// </summary>
        /// <param name="daySlices">拆分的天</param>
        /// <param name="moduleName">PM名称</param>
        /// <param name="gasFlowSumList">显示集合列表</param>
        /// <returns></returns>
        private static DataTable GetProcessHistoryDeviceDataListDaySlices(DateRangeHelper daySlices, string moduleName, List<ProcessDeviceItem> processHistoryItemList)
        {
            DataTable dataTable = null;
            var ts = daySlices.Diff;
            for (var day = 0; day <= ts.Days; day++)
            {
                var tblName = $"{daySlices.Start.AddDays(day):yyyyMMdd}.{moduleName}";
                var sql = new StringBuilder();
                // 检查表名是否存在，否则SQL执行出错。
                if (CheckTableExists(tblName))
                {
                    sql.Append("select time AS InternalTimeStamp");

                    // 添加待查询的列
                    foreach (var item in processHistoryItemList)
                    {
                        // 检查表中是否存在对应属性，否则SQL执行出错。
                        if (CheckPropertyExists(tblName, $"{moduleName}.{item.Property}"))
                        {
                            item.IsPropertyExists = true;
                            sql.Append("," + $"\"{moduleName}.{item.Property}\"");
                        }
                        else//不查询状态标记
                            item.IsPropertyExists = false;
                        
                    }

                    sql.Append($", \"time\"");
                    sql.Append($" from \"{tblName}\"");

                    if (day < ts.Days)
                        sql.Append(" UNION ");
                    sql.Append(
                $" where time between {daySlices.Start.Ticks} and {daySlices.End.Ticks}  order by InternalTimeStamp asc");
                    try
                    {
                        var _dataTable = QueryDataClient.Instance.Service.QueryData(sql.ToString());
                        if (_dataTable is not null && _dataTable.Rows.Count > 0)
                            dataTable = _dataTable;
                    }
                    catch (Exception ex)//查询较早日期时，可能不存在属性会报错
                    {
                    }
                }
            }

            return dataTable;
        }

        private static bool CheckTableExists(string tableName)
        {
            var sql =
                $"SELECT EXISTS ( SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = '{tableName}' )";
            var table = QueryDataClient.Instance.Service.QueryData(sql);
            if (table == null)
                return false;

            if (table.Rows.Count <= 0)
                return false;

            var value = table.Rows[0]["exists"].ToString();
            if (value.ToLower() == "true")
                return true;

            return false;
        }

        private static bool CheckPropertyExists(string tableName, string property)
        {
            var sql =
                $"select count(1) from information_schema.columns WHERE  table_name = '{tableName}' and column_name = '{property}'";
            var table = QueryDataClient.Instance.Service.QueryData(sql);
            if (table == null)
                return false;

            if (table.Rows.Count <= 0)
                return false;

            var value =int.Parse(table.Rows[0]["count"].ToString());
            if (value == 0)
                return false;
            return true;
        }
    }
}