using System;
using System.Collections.Generic;
using System.Text;
using MySql.Data.MySqlClient;
using Dapper;
using solarApp.Model;
using System.Configuration;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace solarApp.Service
{
    public class procArchiveSensorHourly
    {
        string Connection1 = string.Empty;
        ILogger _logger;
        public string _siteID { get; set; }
        public string _siteDB { get; set; }
        public string _siteID01 { get; set; }
        public string _date1 { get; set; }
        //public string _date2 { get; set; }
        public string _powerStationID { get; set; }
        public procArchiveSensorHourly(string Connection_parame = null)
        {
            if (!string.IsNullOrEmpty(Connection_parame))
            {
                Connection1 = Connection_parame;
            }
            else
            {
                Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString;
            }

        }

        public bool get_siteInfo()
        {
            bool result = false;
            try
            {
                using (MySqlConnection conn = new MySqlConnection(Connection1))
                {
                    conn.Open();

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}取得電站編號", _siteID, _date1);
                    }

                    #region 取得 PowerStationID               
                    string sql = @" select id , `code` siteID,  siteDB, `name` siteName 
                                    from solar_master.power_station where `code` = @siteID";
                    var ds = conn.Query<station_list>(sql, new { siteID = _siteID }, commandTimeout: 600).AsList<station_list>();
                    foreach (var item in ds)
                    {
                        _powerStationID = item.id;
                        _siteDB = item.SiteDB;
                        _siteID01 = item.SiteID + "01";
                    }

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}取得電站編號 - {2}", _siteID, _date1, _powerStationID);
                    }

                    #endregion
                    conn.Close();
                }
                result = true;
            }
            catch (Exception ex)
            {
                if (_logger != null)
                {
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}取得電站編號", _siteID, _date1);
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}取得電站編號 - [Exception]：{2}", _siteID, _date1, ex.ToString());
                }

                throw ex;
            }
            return result;
        }

        public bool insertData(string code, string t1)
        {
            _siteID = code;
            _date1 = t1;
            get_siteInfo();
            bool result = false;
            try
            {
                using (MySqlConnection conn = new MySqlConnection(Connection1))
                {
                    conn.Open();

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}設備寫入資料表的資料", _siteID, _date1);
                    }
                    string sql = $@"
                        select x.*, z.itemname,  z.HourType, z.DayType, z.MonthType,z.SetWhat  
                        from (
                          -- No sharedevice 
                          select a.id, uid, a.PowerStationID,   
                          Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, 
                          DBName, TableName, ColName 
                          from {_siteDB}.device a   
                          where  a.powerstationid = {_powerStationID}  
                          and deleted = 0 and Enabled = 1
                          -- has sharedevice
                         union
                          select a.id, uid, b.PowerStationID,  
                          Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, 
                          DBName, TableName, ColName 
                          from {_siteDB}.device a  
                          join {_siteDB}.`SHAREdevice` b on  a.id = b.deviceid 
                          where  b.powerstationid = {_powerStationID}
                          and deleted = 0 and Enabled = 1
                         ) x join sensor_type y on x.sensortypeid = y.id
                         join sensor_type_detail z on y.id = z.SensorTypeId";
                    var ds = conn.Query<SensorTypeInfo>(sql, commandTimeout: 600);
                    StringBuilder sb_inserr = new StringBuilder();
                    StringBuilder sb_select  = new StringBuilder();

                    sb_select.Append($@"select {_powerStationID},  CONCAT('{t1}', ':00:00') as 'TIMESTAMP', ");
                    string irrColName = "";
                    bool isFirst = true;
                    foreach (var item in ds)
                    {
                        if(item.type == "PYR")
                        {
                            irrColName = item.ColName;
                            continue;
                        }
                        if (isFirst)
                        {
                            sb_inserr.Append($@"{item.SetWhat}");
                            sb_select.Append($@"ifnull({item.HourType}({item.ColName}), 0)");
                            isFirst = false;
                        }
                        else
                        {
                            sb_inserr.Append($@", {item.SetWhat}");
                            sb_select.Append($@", {item.HourType}({item.ColName}) ");
                        }
                    }

                    var tb = ds.AsList<SensorTypeInfo>();
                    sb_select.Append($@" from {tb[0].DBName}.{tb[0].TableName} where Left(crdTime, 13) = '{t1}'");
                    string dblocation = tb[0].DBName+"."+tb[0].TableName;
                    sb_inserr.Insert(0, "insert into sensor_history_hour(PowerStationId, TIMESTAMP, ");//sensor_history_hour
                    sb_inserr.Append(") ");
                    string ss = sb_inserr.Append(sb_select.ToString()).ToString();
                    conn.Execute(ss, commandTimeout: 600);
                    if (irrColName != "") 
                    {
                        bool a = countIrr(dblocation, irrColName, t1);
                    }
                    //計算累積日照小時差
                    updateIrrDayHourData(code, t1);

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}設備寫入資料表的資料", _siteID, _date1);
                    }

                    conn.Close();
                }
                result = true;
            }
            catch (Exception ex)
            {
                if (_logger != null)
                {
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備寫入資料表的資料", _siteID, _date1);
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備寫入資料表的資料 - [Exception]：{2}", _siteID, _date1, ex.ToString());
                }
                throw ex;
            }
            return result;
        }

        /// <summary>
        /// 更新日照計
        /// </summary>
        /// <param name="dbName"></param>
        /// <param name="sensorColNum"></param>
        /// <param name="t1"></param>
        /// <returns></returns>
        private bool countIrr(string dbName, string sensorColNum, string t1) {
            bool result = false;
            try
            {
                using (MySqlConnection conn = new MySqlConnection(Connection1))
                {
                    conn.Open();
                    string ss = $@"UPDATE solar_master.sensor_history_hour b 
                            join(select {_powerStationID} as powerstationid, concat(Left(crdTime, 13), ':00:00') ctime , ifnull(avg({sensorColNum}), 0) Irr 
	                        		from {dbName}
	                        		where Left(crdTime, 13) = '{t1}'  and {sensorColNum} <> 0 
	                        	) a ON a.ctime = b.TIMESTAMP AND a.powerstationid = b.powerstationId
                            SET Irradiance = a.Irr";
                     conn.Execute(ss, commandTimeout: 600);
                    conn.Close();
                }
                result = true;
            }
            catch (Exception ex)
            {
                if (_logger != null)
                {
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}日照計更新至資料表的資料", _siteID, _date1);
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}日照計更新至資料表的資料 - [Exception]：{2}", _siteID, _date1, ex.ToString());
                }
                throw ex;
            }
            return result;
        }
        public double updateIrrDayHourData(string code, string t1)
        {
            _siteID = code;
            get_siteInfo();
            string result = "";
            double IrrDayHour = 0;
            double IrrDay = 0;
            double twoHourAgoIrrDay = 0;
            string d1 = t1 + ":00:00";
            try
            {
                using (MySqlConnection conn = new MySqlConnection(Connection1))
                {
                    conn.Open();

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}累積日照差更新至資料表的資料", _siteID, _date1);
                    }
                    //取前累積日照
                    string sql = $@" select  IrrDay
                                   from solar_master.sensor_history_hour z
                                   where powerstationID = {_powerStationID} and LEFT(z.`TIMESTAMP`, 13 ) = '{Convert.ToDateTime(d1).ToString("yyyy-MM-dd HH")}' ";
                    result = conn.QueryFirstOrDefault<string>(sql, commandTimeout: 600);
                    if (result != null)
                    {
                        IrrDay = double.Parse(result);
                    }
                    else
                    {
                        IrrDay = 0;
                    }
                    
                    string sql2 = $@" select  IrrDay
                                   from solar_master.sensor_history_hour z
                                   where powerstationID = {_powerStationID} and LEFT(z.`TIMESTAMP`, 13 ) = '{Convert.ToDateTime(d1).AddHours(-1).ToString("yyyy-MM-dd HH")}' ";
                    result = conn.QueryFirstOrDefault<string>(sql2, commandTimeout: 600);
                    if (result != null)
                    {
                        twoHourAgoIrrDay = double.Parse(result);
                    }
                    else
                    {
                        twoHourAgoIrrDay = 0;
                    }

                    if (Convert.ToDateTime(d1).AddHours(-1).Hour == 0)//半夜12點的值
                    {
                        IrrDayHour = 0;
                    }
                    else
                    {
                        IrrDayHour = IrrDay - twoHourAgoIrrDay;// 前一小時的IrrDay - 前兩小時的IrrDay
                    }
                    if(IrrDayHour < 0)
                    {
                        IrrDayHour = 0;
                    }
                    
                    string ss = $@"UPDATE solar_master.sensor_history_hour
                                   SET IrrDayHour = {IrrDayHour}
                                   WHERE LEFT(TIMESTAMP, 13) = '{t1}' AND PowerStationId = {_powerStationID}";
                    conn.Execute(ss, commandTimeout: 600);
                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}累積日照差更新至資料表的資料", _siteID, _date1);
                    }
                    conn.Close();
                }
            }
            catch (Exception ex)
            {
                if (_logger != null)
                {
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}累積日照差更新資料表的資料", _siteID, _date1);
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}累積日照差更新資料表的資料 - [Exception]：{2}", _siteID, _date1, ex.ToString());
                }
                throw ex;
            }
            return IrrDayHour;
        }

        public bool clearData()
        {
            bool result = false;
            try
            {
                using (MySqlConnection conn = new MySqlConnection(Connection1))
                {
                    conn.Open();

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}設備清除資料表的資料", _siteID, _date1);
                    }
                    string d1 = _date1 + ":00:00";
                    string clearTime = Convert.ToDateTime(d1).ToString("yyyy-MM-dd");
                    string sql = @"delete from solar_master.sensor_history_hour where powerstationID = @powerStationID and  left(TIMESTAMP, 10) = @date1";
                    MySqlCommand cmd = new MySqlCommand();
                    cmd.Connection = conn;
                    cmd.CommandTimeout = 600;
                    cmd.Parameters.AddWithValue("@date1", clearTime);
                    cmd.Parameters.AddWithValue("@PowerStationID", _powerStationID);
                    cmd.CommandText = sql;
                    cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();

                    if (_logger != null)
                    {
                        _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}設備清除資料表的資料", _siteID, _date1);
                    }

                    conn.Close();
                }
                result = true;
            }
            catch (Exception ex)
            {
                if (_logger != null)
                {
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備清除資料表的資料", _siteID, _date1);
                    _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備清除資料表的資料 - [Exception]：{2}", _siteID, _date1, ex.ToString());
                }
                throw ex;
            }
            return result;
        }

    }
}
