using MECF.Framework.Common.Aitex.Core.Common.DeviceData;
using MECF.Framework.Common.DataCenter;
using Sicentury.Core;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.GasFlow
{
    /// <summary>
    /// 气体流量统计，根据输入名称和时间来查询
    /// </summary>
    public class GasFlowSqlHelp
    {
        

        /// <summary>
        /// 查询当天的气体体积数据
        /// </summary>
        /// <param name="daySlices">拆分的天</param>
        /// <param name="moduleName">PM名称</param>
        /// <param name="gasFlowSumList">显示列表对象</param>
        /// <returns></returns>
        public static List<GasFlowSum> GetDayGasFlowSum(DateRangeHelper daySlices, string moduleName, List<GasFlowSum> gasFlowSumList)
        {
            List<DataTable> dataTableList = GetAllGasListDaySlices(daySlices, moduleName, gasFlowSumList);

            string rowStr;

            List<GasFlowSum> GasFlowrRunVentList = new List<GasFlowSum>();

            foreach (var item in gasFlowSumList)
            {
                GasFlowrRunVentList.Add(new GasFlowSum() { Name = $"{item.Name}_Run" });
                GasFlowrRunVentList.Add(new GasFlowSum() { Name = $"{item.Name}_Vent" });
            }
            foreach (DataTable ds in dataTableList)
            {
                double timeDifference = 0;
                for (int i = 0; i < ds.Rows.Count; i++)
                {
                    foreach (var item in GasFlowrRunVentList)
                    {
                        //$"{moduleName}.GasRealTimeFlow.{item.Name}_Run.FeedBack"
                        string property = $"{moduleName}.GasRealTimeFlow.{item.Name}.FeedBack";
                        rowStr = ds.Rows[i][property].ToString();
                        if (rowStr is not null && rowStr.Length == 0)
                            continue;
                        double bd = double.Parse(ds.Rows[i][property].ToString());
                        if (bd > 0)
                        {

                            if (i != ds.Rows.Count - 1)//最后一个数据使用的时间差，是它前一个计算得到的
                            {
                                var startTime = new DateTime(long.Parse(ds.Rows[i]["time"].ToString()));
                                var endTime = new DateTime(long.Parse(ds.Rows[i + 1]["time"].ToString()));
                                timeDifference = (endTime - startTime).TotalSeconds;
                            }
                            item.Volume += bd * timeDifference;
                        }

                    }
                }
            }
            return GasFlowrRunVentList;
        }

        /// <summary>
        /// 根据拆分的天循查询数据
        /// </summary>
        /// <param name="daySlices">拆分的天</param>
        /// <param name="moduleName">PM名称</param>
        /// <param name="gasFlowSumList">显示集合列表</param>
        /// <returns></returns>
        private static List<DataTable> GetAllGasListDaySlices(DateRangeHelper daySlices, string moduleName, List<GasFlowSum> gasFlowSumList)
        {
            List<DataTable> dataTableList = new List<DataTable>();
            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 gasFlowSumList)
                    {
                        sql.Append("," + $"\"{moduleName}.GasRealTimeFlow.{item.Name}_Run.FeedBack\"");

                        sql.Append("," + $"\"{moduleName}.GasRealTimeFlow.{item.Name}_Vent.FeedBack\"");
                    }

                    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 dataSet = QueryDataClient.Instance.Service.QueryData(sql.ToString());
                        if (dataSet is not null && dataSet.Rows.Count > 0)
                            dataTableList.Add(dataSet);
                    }
                    catch (Exception ex)//查询较早日期时，可能不存在属性会报错
                    {

                    }

                }
            }

            return dataTableList;
        }

        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;
        }


        public static List<DataTable> GetDataSetDaySlices(DateRangeHelper daySlices, string tableName, string propertyCmd, string property)
        {
            List<DataTable> dataTableList = new List<DataTable>();
                var ts = daySlices.Diff;
                for (var day = 0; day <= ts.Days; day++)
                {
                    var tblName = $"{daySlices.Start.AddDays(day):yyyyMMdd}.{tableName}";
                    var sql = new StringBuilder();
                    // 检查表名是否存在，否则SQL执行出错。
                    if (CheckTableExists(tblName))
                    {
                        sql.Append("select time AS InternalTimeStamp");
                        // 添加待查询的列
                        sql.Append(propertyCmd);
                        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} and '{property}' is not NULL  order by InternalTimeStamp asc");
                        try
                        {
                            var dataSet = QueryDataClient.Instance.Service.QueryData(sql.ToString());
                            if (dataSet is not null && dataSet.Rows.Count > 0)
                                dataTableList.Add(dataSet);
                        }
                        catch (Exception ex)//查询较早日期时，可能不存在属性会报错
                        {

                        }

                    }
                }
            
            return dataTableList;
        }

        

        public static double GetData(List<DataTable> dataTableList, string property)
        {
            double values = 0;
            string rowStr;
            foreach (DataTable ds in dataTableList)
            {
                double timeDifference = 0;
                for (int i = 0; i < ds.Rows.Count; i++)
                {
                    rowStr = ds.Rows[i][property].ToString();
                    if (rowStr is not null && rowStr.Length == 0)
                        continue;
                    double bd = double.Parse(ds.Rows[i][property].ToString());
                    if (bd > 0)
                    {

                        if (i != ds.Rows.Count - 1)//最后一个数据使用的时间差，是它前一个计算得到的
                        {
                            var startTime = new DateTime(long.Parse(ds.Rows[i]["time"].ToString()));
                            var endTime = new DateTime(long.Parse(ds.Rows[i + 1]["time"].ToString()));
                            timeDifference = (endTime - startTime).TotalSeconds;
                        }
                        values += bd * timeDifference;
                    }
                }
            }
            return values;
        }

        
    }
}
