using System;
using System.Collections.Generic;
using System.Text;
using MySql.Data.MySqlClient;
using Dapper;
using solarApp.Model;
using System.Configuration;

namespace solarApp.Service
{
    public  class getSensorSvc
    {
        string Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString;
        /// <summary>
        /// 電站 Raw Data
        /// </summary>
        /// <param name="reportDate"></param>
        /// <param name="siteDB"></param>
        /// <param name="siteID"></param>
        /// <returns></returns>
        public List<sensor_raw> get_sensor_raw(string reportDate, string siteDB, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @"select siteid , FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H:%i') reportdate, round(sensorAvg01, 3) sensorAvg01, round(sensorAvg02, 3) sensorAvg02, 
                                      round(sensorAvg03, 3) sensorAvg03, round(sensorAvg04, 3) sensorAvg04, round(sensorAvg05, 3) sensorAvg05, round(sensorAvg06, 3) sensorAvg06
	                    from " + siteDB + ".s" + siteID + @"_sensorAvg  
	                    where left(FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H:%i'), 10) =  @reportDate";
                List<sensor_raw> ds = conn.Query<sensor_raw>(sql, new { reportDate = reportDate }).AsList<sensor_raw>();
                conn.Close();
                return ds;
            }
        }

        /// <summary>
        /// 取得需要補償的 Sensor 資料
        /// </summary>
        /// <param name="reportDate"></param> 
        /// <returns></returns>
        public List<lackData> get_lack_sensorData(string reportDate)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select  a.powerstationid, p.`code` SITEID, a.`TIMESTAMP` , TODAYKWH, TOTALKWH , b.Irradiance, b.EnvTemperature, b.irrDay #累計日照量
	                            from power_station_history_hour a 
	                            left join (
							                select PowerStationID, `TIMESTAMP` , Irradiance, Temperature, EnvTemperature, Humidity, Vane, Dust, WingDirection, irrDay 
							                from sensor_history_hour
							                where   left(`TIMESTAMP`, 7) = @reportDate and hour(`TIMESTAMP`) = 12
						                 ) b on a.powerstationid = b.powerstationid and a.`TIMESTAMP` = b.`TIMESTAMP` 
                                join power_station p on a.powerstationid = p.id		
	                            where  left(a.`TIMESTAMP`, 7) = @reportDate and hour(a.`TIMESTAMP`) = 12 and b.Irradiance is null
	                            order by 1, 2";
                List<lackData> ds = conn.Query<lackData>(sql, new { reportDate = reportDate.Substring(0, 7) }).AsList<lackData>();
                conn.Close();
                return ds;
            }
        }

        /// <summary>
        /// Sensor 欄位需要平均時 欄位串接 (s1 + s2) / 2
        /// </summary>
        /// <param name="lstData"></param>
        /// <returns></returns>
        string ConcatColumn(List<sensor_model> lstData) 
        {
            string ss = string.Empty; string result = string.Empty;
            if (lstData.Count > 0)
            {
                foreach (var item in lstData)
                {
                    ss += (ss == string.Empty) ? item.colname : "+" + item.colname; // 2 個以上欄位需要相加
                }
                if (lstData.Count >= 2 && lstData[0].type == "PYR") result = "round( avg( " +  ss + ") / " + lstData.Count.ToString() + " , 2) "; //日照計 2個以上 需要除以個數 (平均值)
                else
                    result = "round( avg(" +  ss + " ), 2) ";
            }
            else result = "0";
            return result;
        }

        public List<sensor_raw_V2> get_sensor_raw_hour(string reportDate, string siteDB, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();

                // init 關閉 group full column 
                string ss = @"SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY,',''));";
                conn.Execute(ss);



                #region 獲取 Sensor 類別
                string sql = @"select a.id,  CONCAT( left(UID, 9) ,'01') SiteID, a.`name` sensorName, type, DBName, TableName, colname 
                                from " + siteDB + @".device a
                                where left(UID, 11)  = @siteID";
                List<sensor_model> ds_sensor = conn.Query<sensor_model>(sql, new { siteID = siteID}).AsList<sensor_model>();

                //欄位處理
                // {  "Type":[
                //   { "Name":"日照計","EName":"PYR"},
                //   { "Name":"模組溫度計","EName":"MTR"},
                //   { "Name":"環境溫度計","EName":"ETR"},
                //   { "Name":"環境濕度計","EName":"EMM"},
                //   { "Name":"風速計","EName":"VAN"},
                //   { "Name":" 電表","EName":"PWR"}]}
                //   { "Name":" 累計日照量","EName":"TPY"}]}

                var irrlst = ds_sensor.FindAll(x => x.type.Contains("PYR"));
                var modelTemplst = ds_sensor.FindAll(x => x.type.Contains("MTR"));
                var envTemplst = ds_sensor.FindAll(x => x.type.Contains("ETR"));
                var humlst = ds_sensor.FindAll(x => x.type.Contains("EMM"));
                var windlst = ds_sensor.FindAll(x => x.type.Contains("VAN"));
                var dustlst = ds_sensor.FindAll(x => x.type.Contains("DST")); //需要新增於DB
                var totIrrlst = ds_sensor.FindAll(x => x.type.Contains("TPY")); //累計日照量
                //var meterlst = ds_sensor.FindAll(x => x.type.Contains("PWR"));  電錶暫不處理
                string irrCol = string.Empty; string modelTempCol = string.Empty; string evnTempCol = string.Empty; string humCol = string.Empty; string windCol = string.Empty; string  meterCol = string.Empty; string dustCol = string.Empty; string totIrrCol = string.Empty;
                irrCol = ConcatColumn(irrlst);//日照計
                modelTempCol = ConcatColumn(modelTemplst);
                evnTempCol = ConcatColumn(envTemplst);
                humCol = ConcatColumn(humlst);
                windCol = ConcatColumn(windlst);
                dustCol = ConcatColumn(dustlst);
                totIrrCol = ConcatColumn(totIrrlst);

                string irrNot0 = string.Empty; // and 日照1 <> 0    and 日照2 <> 0
                # region 日照計需要過濾 0 
                if (irrlst.Count > 0)
                {
                    foreach (var item in irrlst) 
                        irrNot0 += " and " + item.colname + " <> 0 ";  // and S1 <> 0    and S2 <> 0
                }
                #endregion 

                //電表
                #endregion 獲取 Sensor 類別
                sql = @"select a.siteID, a.reportdate, a.modelTempAvg, irrSumAvg, a.envTempAvg, humidityAvg, windAvg, dustAvg, ifnull(b.irrAvg, 0) irrAvg, count from 
                            (
		                            select @siteID siteID, CONCAT( FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H'), ':00') reportdate, " + modelTempCol+ @" modelTempAvg , " + totIrrCol + @" irrSumAvg 
					                       ," + evnTempCol + @" envTempAvg,  " + humCol + @"  humidityAvg, " + windCol + @" windAvg,  " + dustCol + @" dustAvg, count(*) count
		                            from   " + siteDB + ".s" + siteID + @"_sensorAvg  
		                            where FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d') =  @reportDate
		                            group by  FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H') 
                            ) a left join 
                            (
	 	                            select CONCAT( FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H'), ':00') reportdate , " + irrCol + @"  irrAvg
		                            from   " + siteDB + ".s" + siteID + @"_sensorAvg  
		                            where FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d') =  @reportDate "+ irrNot0 + @" #需要過濾 0 的數值 
		                            group by FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H') 
                            )b on a.reportdate = b.reportdate";
                List<sensor_raw_V2> ds = conn.Query<sensor_raw_V2>(sql, new { siteID = siteID, reportDate = reportDate }).AsList<sensor_raw_V2>();
                conn.Close();
                return ds;
            }
        }

        /// <summary>
        /// web 呈現值 station - hour
        /// </summary>
        /// <param name="reportDate"></param>
        /// <returns></returns>
        public List<sensor_hour> get_web_sensor_hour(string reportDate, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, round(Temperature, 2) modelTempAvg, round(irrDay, 2) irrSumAvg, round(Irradiance, 2) irrAvg
                                from sensor_history_hour a join power_station b on a.PowerStationId = b.id 
                                where left(`TIMESTAMP`, 10) = '" + reportDate + "' and b.`code` = @siteID";
                List<sensor_hour> ds = conn.Query<sensor_hour>(sql, new {siteID = siteID }).AsList<sensor_hour>();
                conn.Close();
                return ds;
            }
        }

        public List<sensor_hour> get_web_sensor_day(string date1, string date2, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                //string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, round(Irradiance, 2) irrAvg, round(Temperature, 2) modelTempAvg
                //                from sensor_history_day a join power_station b on a.PowerStationId = b.id 
                //                where left(`TIMESTAMP`, 10) between '" + date1 + "' and '"+date2+"' and b.`code` = @siteID";
                string sql = @"select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid,  round(Temperature, 2) modelTempAvg, round(irrDay, 2) irrSumAvg, round(Irradiance, 2) irrAvg, c.count
                                from sensor_history_day a join power_station b on a.PowerStationId = b.id 
                                left join    (
		                            select PowerStationId, left(a.`TIMESTAMP`, 10) reportDate, count(*) count from sensor_history_hour a join power_station b on a.PowerStationId = b.id 
		                            where b.`code` = @siteID and left(`TIMESTAMP`, 10) between '" + date1 + "' and '" + date2 + @"'
                                    group by PowerStationId,  left(a.`TIMESTAMP`, 10)
                                )c on a.PowerStationId = c.PowerStationId and  DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d') = c.reportDate
                                where left(a.`TIMESTAMP`, 10) between '" + date1 + "' and '" + date2 + @"' and b.`code` = @siteID";
                List<sensor_hour> ds = conn.Query<sensor_hour>(sql, new { siteID = siteID }).AsList<sensor_hour>();
                conn.Close();
                return ds;
            }
        }

        public List<sensor_hour> get_web_sensor_month(string date1, string date2, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, round(irrDay, 2) irrSumAvg , round(Temperature, 2) modelTempAvg, round(Irradiance, 2) irrAvg
                                from sensor_history_month a join power_station b on a.PowerStationId = b.id 
                                where left(`TIMESTAMP`, 7) between '" + date1 + "' and '" + date2 + "' and b.`code` = @siteID";
                List<sensor_hour> ds = conn.Query<sensor_hour>(sql, new { siteID = siteID}).AsList<sensor_hour>();
                conn.Close();
                return ds;
            }
        }


        public List<sensor_raw> get_web_sensor50_hour(string reportDate, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, sensorAVG01, sensorAVG02, sensorAVG03, sensorAVG04, sensorAVG05, sensorAVG06
                                from sensoravg_history_hour a join power_station b on a.PowerStationId = b.id 
                                where left(`TIMESTAMP`, 10) = '" + reportDate + "' and b.`code` = @siteID";
                List<sensor_raw> ds = conn.Query<sensor_raw>(sql, new { siteID = siteID }).AsList<sensor_raw>();
                conn.Close();
                return ds;
            }
        }

        public List<sensor_raw> get_web_sensor50_day(string date1, string date2, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, sensorAVG01, sensorAVG02, sensorAVG03, sensorAVG04, sensorAVG05, sensorAVG06
                                from sensoravg_history_day a join power_station b on a.PowerStationId = b.id 
                                where left(`TIMESTAMP`, 10) between @date1 and @date2 and b.`code` = @siteID";
                List<sensor_raw> ds = conn.Query<sensor_raw>(sql, new { siteID = siteID, date1 = date1, date2 = date2 }).AsList<sensor_raw>();
                conn.Close();
                return ds;
            }
        }

        public List<sensor_raw> get_web_sensor50_month(string date1, string date2, string siteID)
        {
            using (MySqlConnection conn = new MySqlConnection(Connection1))
            {
                conn.Open();
                string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, b.`code` siteid, sensorAVG01, sensorAVG02, sensorAVG03, sensorAVG04, sensorAVG05, sensorAVG06
                                from sensoravg_history_month a join power_station b on a.PowerStationId = b.id 
                                where left(`TIMESTAMP`, 7) between @date1 and @date2 and b.`code` = @siteID";
                List<sensor_raw> ds = conn.Query<sensor_raw>(sql, new { siteID = siteID, date1 = date1, date2 = date2 }).AsList<sensor_raw>();
                conn.Close();
                return ds;
            }
        }
    }
}
