using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz;
using SolarPower.Models.PowerStation;
using SolarPower.Repository.Interface;
using SolarPower.Services.Implement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;

namespace SolarPower.Quartz.Jobs
{
    [DisallowConcurrentExecution]
    public class CalcPowerStationJobV2 : IJob
    {
        private readonly ILogger<CalcPowerStationJobV2> logger;
        private readonly IPowerStationRepository powerStationRepository;
        private readonly IConfiguration Configuration;

        public IWebHostEnvironment environment;

        private double carbonRate;
        string calcPowerStationTime = "";

        public CalcPowerStationJobV2(
            ILogger<CalcPowerStationJobV2> logger,
            IPowerStationRepository powerStationRepository,
            IWebHostEnvironment environment,
            IConfiguration Configuration)
        {
            this.logger = logger;
            this.powerStationRepository = powerStationRepository;
            this.environment = environment;
            this.Configuration = Configuration;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                var DateTimeNow = DateTime.Now;
                var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH");
                logger.LogInformation("【CalcPowerStationJobV2】【任務開始】");

                #region step1. 找出所有電站
                logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站資料】");
                var powerStations = await powerStationRepository.GetAllAsync();
                logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站資料】");
                logger.LogInformation("【CalcPowerStationJobV2】【電站資料");
                #endregion

                await ArchiveStation(powerStations, dateTime);
                await ArchiveStationForPowerStationWithWinForm(powerStations, dateTime);
                await ArchiveSensorWithWinForm(powerStations, dateTime);
                await ArchiveInverter(powerStations, dateTime);
                await ArchiveSensoravg(powerStations, dateTime);
                await ArchiveMeter(powerStations, dateTime);
                await ArchiveWeather(powerStations, dateTime);

                logger.LogInformation("【CalcPowerStationJobV2】【任務完成】");
            }
            catch (Exception exception)
            {
                logger.LogError("【CalcPowerStationJobV2】[Exception] - {0}", exception.Message);
                if (exception.InnerException != null)
                {
                    logger.LogError("【CalcPowerStationJobV2】[InnerException] - {0}", exception.InnerException.Message);
                }
            }
        }

        private async Task ArchiveStation(List<PowerStation> powerStations, string dateTime)
        {
            List<PowerStationHistory> powerStationHistoriesHour = new List<PowerStationHistory>();
            List<PowerStation> calcPowerStations = new List<PowerStation>();
            foreach (var powerStation in powerStations)
            {
                try
                {
                    #region step2-1. 取得該電站的當前這小時的歷史資料
                    var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code);
                    var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name);
                    var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name);

                    if (string.IsNullOrEmpty(exist))
                    {
                        logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_station資料表】");
                    }
                    else
                    {
                        logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                        var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name);

                        if (history == null)
                        {
                            logger.LogWarning("【CalcPowerStationJobV2】【查無電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                        }
                        else
                        {
                            logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                            logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history));

                            logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                            history.PowerStationId = powerStation.Id;
                            history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");

                            #region 計算單一電站每小時發電量、發電金額等資料 for history

                            #region 發電金額
                            history.MONEY = history.KWH * powerStation.PowerRate;
                            history.TODAYMONEY = history.TodayKWh * powerStation.PowerRate;
                            history.TOTALMONEY = history.TotalKWH * powerStation.PowerRate;
                            #endregion

                            #region 減碳量
                            carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate"));
                            history.CARBON = history.KWH * carbonRate;
                            history.TODAYCARBON = history.TodayKWh * carbonRate;
                            history.TOTALCARBON = history.TotalKWH * carbonRate;
                            #endregion

                            #endregion

                            powerStationHistoriesHour.Add(history);

                            logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                        }
                    }
                    #endregion
                }
                catch (Exception exception)
                {
                    logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
            //if (!environment.IsDevelopment())
            //{
                #region step3. 將historiers INSERT 到 power_station_history_hour 資料表
                List<string> history_properties = new List<string>()
                    {
                        "PowerStationId",
                        "TIMESTAMP",
                        "SITEID",
                        "SITETYPE",
                        "KWH",
                        "TODAYKWH",
                        "TOTALKWH",
                        "KWHKWP",
                        "PR",
                        "MP",
                        "SolarHour",
                        "MONEY",
                        "CARBON",
                        "TODAYMONEY",
                        "TOTALMONEY",
                        "TODAYCARBON",
                        "TOTALCARBON"
                    };
                logger.LogInformation("【Insert PowerStationHistoryHour】【ArchiveStation】【開始寫入 PowerStationHistoryHour 資料】- {0}", dateTime);
                await powerStationRepository.AddPowerStationHistory(powerStationHistoriesHour, history_properties);
                logger.LogInformation("【Insert PowerStationHistoryHour】【ArchiveStation】【完成寫入 PowerStationHistoryHour 資料】- {0}", dateTime);
                #endregion
            //}
        }

        private async Task ArchiveStationForPowerStation(List<PowerStation> powerStations, string dateTime)
        {
            List<PowerStationHistory> powerStationHistoriesHour = new List<PowerStationHistory>();
            List<PowerStation> calcPowerStations = new List<PowerStation>();
            foreach (var powerStation in powerStations)
            {
                try
                {
                    var calcPowerStation = new PowerStation();
                    calcPowerStation.Id = powerStation.Id;
                    #region step2-1. 取得該電站的當前這小時的歷史資料
                    var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code);
                    var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name);
                    var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name);

                    if (string.IsNullOrEmpty(exist))
                    {
                        logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_station資料表】");
                    }
                    else
                    {
                        #region 計算單一電站每小時發電量、發電金額等資料 for calcPowerStation
                        var dateTimeforPowerStation = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd");//取當天
                        logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的每小時歷史資料 for calcPowerStation】", powerStation.Code, dateTimeforPowerStation);
                        var history_for_powerStation = await powerStationRepository.GetPowerStationHistoryPerHourForPowerStation(dateTimeforPowerStation, full_table_name);
                        if (history_for_powerStation == null)
                        {
                            logger.LogWarning("【CalcPowerStationJobV2】【查無電站[{0}]在{1}的每小時歷史資料 for calcPowerStation；發電量、發電金額等資料設定為0】", powerStation.Code, dateTimeforPowerStation);
                            calcPowerStation.kwh = 0;
                            calcPowerStation.Today_kWh = 0;
                            calcPowerStation.Total_kWh = 0;
                            calcPowerStation.Today_Money = 0;
                            calcPowerStation.Total_Money = 0;
                            calcPowerStation.Today_kwhkwp = 0;
                            calcPowerStation.Today_PR = 0;
                            calcPowerStation.Today_Carbon = 0;
                            calcPowerStation.Total_Carbon = 0;
                            calcPowerStation.SolarHour = 0;
                        }
                        else
                        {
                            logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的每小時歷史資料 for calcPowerStation】", powerStation.Code, dateTimeforPowerStation);
                            #region 發電量
                            //每小時發電量(直接填寫
                            calcPowerStation.kwh = history_for_powerStation.KWH;
                            //今日發電量(直接填寫
                            calcPowerStation.Today_kWh = history_for_powerStation.TodayKWh;
                            //總發電量(直接填寫
                            calcPowerStation.Total_kWh = history_for_powerStation.TotalKWH;
                            #endregion

                            #region 發電金額
                            history_for_powerStation.MONEY = history_for_powerStation.KWH * powerStation.PowerRate;
                            history_for_powerStation.TODAYMONEY = history_for_powerStation.TodayKWh * powerStation.PowerRate;
                            history_for_powerStation.TOTALMONEY = history_for_powerStation.TotalKWH * powerStation.PowerRate;

                            //即時發電金額
                            switch (powerStation.SolarType)
                            {
                                case (int)SolarTypeEnum.SelfSold: //自建躉售 
                                                                  //今日發電金額 計算方式：todaykWh * 授電費率
                                    calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate;

                                    ////總發電金額 計算方式：totalkWh * 授電費率
                                    calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate;
                                    break;
                                case (int)SolarTypeEnum.HireSold: //租建躉售 
                                                                  //找出該電站的所有土地房屋資訊
                                    var landBuildings = await powerStationRepository.GetAllLandBuildingInfoByPowerStationId(powerStation.Id, powerStation.SiteDB);
                                    var sumLeaseRate = 0.00;
                                    var avgLeaseRate = 0.00;

                                    foreach (var landBuilding in landBuildings)
                                    {
                                        sumLeaseRate += landBuilding.LeaseRate;
                                    }

                                    calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate * sumLeaseRate / 100;
                                    calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate * sumLeaseRate / 100;

                                    break;
                                case (int)SolarTypeEnum.SelfUse: //自建自用 

                                    //今日發電金額 計算方式：todaykWh * 授電費率
                                    calcPowerStation.Today_Money = history_for_powerStation.TodayKWh * powerStation.PowerRate;

                                    //總發電金額 計算方式：totalkWh * 授電費率
                                    calcPowerStation.Total_Money = history_for_powerStation.TotalKWH * powerStation.PowerRate;
                                    break;
                            }
                            #endregion

                            #region kWh/kWp
                            ////直接填寫
                            calcPowerStation.Today_kwhkwp = history_for_powerStation.KWHKWP;
                            #endregion

                            #region PR
                            //直接填寫
                            calcPowerStation.Today_PR = history_for_powerStation.PR;
                            #endregion

                            #region 減碳量
                            carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate"));
                            history_for_powerStation.CARBON = history_for_powerStation.KWH * carbonRate;
                            history_for_powerStation.TODAYCARBON = history_for_powerStation.TodayKWh * carbonRate;
                            history_for_powerStation.TOTALCARBON = history_for_powerStation.TotalKWH * carbonRate;

                            //今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值]
                            calcPowerStation.Today_Carbon = history_for_powerStation.TodayKWh * carbonRate;

                            //總減碳量(總發電量 * (0.554/1000)[抓資料庫值]
                            calcPowerStation.Total_Carbon = history_for_powerStation.TotalKWH * carbonRate;
                            #endregion

                            #region 發電時間
                            calcPowerStation.SolarHour = history_for_powerStation.SolarHour;
                            #endregion

                            #region 取拿到資料的時間
                            calcPowerStationTime = history_for_powerStation.Timestamp;
                            #endregion
                        }
                        #endregion

                        string dateTimeForCalc;
                        if (calcPowerStationTime != "")
                        {
                            dateTimeForCalc = calcPowerStationTime;
                        }
                        else
                        {
                            dateTimeForCalc = dateTime;
                        }

                        logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
                        var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB);
                        logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
                        logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos));

                        if (deviceInfos != null && deviceInfos.Count() > 0)
                        {
                            var pyrheliometerHistory_for_calcPowerStation = await powerStationRepository.CalcSensorHistoryPerHour(dateTimeForCalc, deviceInfos, Convert.ToInt32(SensorTypeEnum.PYR));
                            if (pyrheliometerHistory_for_calcPowerStation != null)
                            {
                                calcPowerStation.Today_irradiance = pyrheliometerHistory_for_calcPowerStation.Irradiance;
                                logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的日照計的平均值】", powerStation.Code, dateTime);
                            }
                            else
                            {
                                logger.LogWarning("【CalcPowerStationJobV2】【查無結果電站[{0}]在{1}的日照計的平均值】", powerStation.Code, dateTime);
                            }
                        }
                        calcPowerStations.Add(calcPowerStation);
                        logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
                    }
                    #endregion
                }
                catch (Exception exception)
                {
                    logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveStation】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
            //if (!environment.IsDevelopment())
            //{
                #region step5. calcPowerStations UPDATE 到 power_station 資料表
                List<string> power_station_properties = new List<string>()
                    {
                        "Id",
                        "kwh",
                        "Today_kwh",
                        "Total_kwh",
                        "today_kwhkwp",
                        "today_money",
                        "total_money",
                        "today_PR",
                        "today_carbon",
                        "total_carbon",
                        "today_irradiance",
                        "SolarHour",
                        "WeathersStationId",
                        "TodayWeatherTemp",
                        "TodayWeather",
                        "RateOfRain"
                    };
                logger.LogInformation("【update Power_Station】【ArchiveStation】【開始更新 Power_Station 資料】- {0}", dateTime);
                await powerStationRepository.UpdateList(calcPowerStations, power_station_properties);
                logger.LogInformation("【update Power_Station】【ArchiveStation】【完成更新 Power_Station 資料】- {0}", dateTime);
                #endregion
            //}
        }

        private async Task ArchiveStationForPowerStationWithWinForm(List<PowerStation> powerStations, string dateTime)
        {
            logger.LogInformation("【CalcPowerStationJobV2】【開始計算全電站在{0}的發電量等資訊】",  dateTime);
            #region  step2-2. 取得該電站的當前這小時的發電量等歷史資料
            //使用winform function
            var Connection_string = Configuration.GetValue<string>("mySql");
            SensorHourlyService sensorHourlyService = new SensorHourlyService(Connection_string);
            await sensorHourlyService.ArchiveStationHourly();
            logger.LogInformation("【CalcPowerStationJobV2】【更新完成全電站在{0}的發電量等資訊】", dateTime);
            #endregion
        }

        private async Task ArchiveSensorWithWinForm(List<PowerStation> powerStations, string dateTime)
        {
            foreach (var powerStation in powerStations)
            {
                try
                {
                    var sensoravg_table_name = String.Format("s{1}01_sensoravg", powerStation.SiteDB, powerStation.Code);
                    var full_sensoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, sensoravg_table_name);
                    var sensoravg_table_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, sensoravg_table_name);
                    if (string.IsNullOrEmpty(sensoravg_table_exist))
                    {
                        logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_sensoravg資料表】");
                    }
                    else
                    {
                        logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的設備資訊】", powerStation.Code, dateTime);
                        #region  step2-2. 取得該電站的當前這小時的設備歷史資料
                        //使用winform function
                        var Connection_string = Configuration.GetValue<string>("mySql");
                        SensorHourlyService sensorHourlyService = new SensorHourlyService(Connection_string);
                        sensorHourlyService.ArchiveSensorHourly(powerStation.Code, dateTime);
                        logger.LogInformation("【CalcPowerStationJobV2】【更新完成電站[{0}]在{1}的設備資訊】", powerStation.Code, dateTime);
                        #endregion
                    }
                }
                catch (Exception exception)
                {
                    logger.LogError("【CalcPowerStationJobV2】【ArchiveSensor】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveSensor】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
        }

        private async Task ArchiveInverter(List<PowerStation> powerStations, string dateTime)
        {
            List<InverterHistory> inverterHistoriesHour = new List<InverterHistory>();
            foreach (var powerStation in powerStations)
            {
                #region step2-3. 計算該電站所有逆變器每小時值

                var inverter_table_name = String.Format("s{0}01_inv", powerStation.Code);
                var full_inverter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, inverter_table_name);
                var inverter_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name);
                if (string.IsNullOrEmpty(inverter_exist))
                {
                    logger.LogError("【CalcPowerStationJobV2】【查無電站[0]的s{0}01_inv資料表】", powerStation.Code);
                }
                else
                {
                    try
                    {
                        logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
                        var controllers = await powerStationRepository.GetAllDeviceControllerId(powerStation.Id, powerStation.SiteDB);
                        var inverters = await powerStationRepository.InverterTable(controllers, powerStation.SiteDB);
                        var inverterIds = inverters.Where(x => x.Enabled == 1 && x.Status != 0).Select(x => x.InverterId).ToList();
                        logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
                        logger.LogInformation("【CalcPowerStationJobV2】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds));

                        if (inverterIds != null && inverterIds.Count() > 0)
                        {
                            logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
                            var inverterHistories = await powerStationRepository.CalcInverterHisyortHourData(dateTime, powerStation.SiteDB, full_inverter_table_name, inverterIds);
                            //取得日照計要找的欄位資訊
                            var pyrheliometer = await powerStationRepository.GetFirstPyrheliometerInfo(powerStation.Id, powerStation.SiteDB);
                            var pyrheliometerValue = await powerStationRepository.GetFirstPyrheliometerValue(dateTime, pyrheliometer.DBName, pyrheliometer.TableName, pyrheliometer.ColName);
                            foreach (var inverterHistory in inverterHistories)
                            {
                                inverterHistory.Irradiance = pyrheliometerValue;
                                inverterHistory.DC1KW = inverterHistory.DC1W / 1000;
                                inverterHistory.DC2KW = inverterHistory.DC2W / 1000;
                                inverterHistory.DC3KW = inverterHistory.DC3W / 1000;
                                inverterHistory.DC4KW = inverterHistory.DC4W / 1000;
                                inverterHistory.DC5KW = inverterHistory.DC5W / 1000;

                                inverterHistory.DCKW = (inverterHistory.DC1W + inverterHistory.DC2W + inverterHistory.DC3W + inverterHistory.DC4W + inverterHistory.DC5W) / 1000;
                                inverterHistory.ACKW = (inverterHistory.AC1W + inverterHistory.AC2W + inverterHistory.AC3W) / 1000;

                                inverterHistory.TIMESTAMP = Convert.ToDateTime(inverterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
                                inverterHistory.PowerStationId = powerStation.Id;

                                inverterHistoriesHour.Add(inverterHistory);
                            }
                            logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveInverter】【計算失敗電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveInverter】【失敗原因】- {0}", ex.Message);
                    }
                }
                #endregion
            }
            //if (!environment.IsDevelopment())
            //{
                #region step6. 將 inverter INSERT 到 inverter_history_hour 資料表
                List<string> inverter_history_properties = new List<string>()
                            {
                                "PowerStationId",
                                "INVERTERID",
                                "TIMESTAMP",
                                "Irradiance",
                                "AC1V",
                                "AC1A",
                                "AC1W",
                                "AC1F",
                                "AC1WH",
                                "AC2V",
                                "AC2A",
                                "AC2W",
                                "AC2F",
                                "AC2WH",
                                "AC3V",
                                "AC3A",
                                "AC3W",
                                "AC3F",
                                "AC3WH",
                                "DC1V",
                                "DC1A",
                                "DC1W",
                                "DC1KW",
                                "DC1WH",
                                "DC2V",
                                "DC2A",
                                "DC2W",
                                "DC2KW",
                                "DC2WH",
                                "DC3V",
                                "DC3A",
                                "DC3W",
                                "DC3KW",
                                "DC3WH",
                                "DC4V",
                                "DC4A",
                                "DC4W",
                                "DC4KW",
                                "DC4WH",
                                "DC5V",
                                "DC5A",
                                "DC5W",
                                "DC5KW",
                                "DC5WH",
                                "PR",
                                "RA1",
                                "RA2",
                                "RA3",
                                "RA4",
                                "RA5",
                                "DCKW",
                                "ACKW",
                                "KWH",
                                "TODAYKWH",
                                "TOTALKWH",
                                "KWHKWP",
                            };
                logger.LogInformation("【Insert InverterHistoryHour】【ArchiveInverter】【開始寫入 inverter_history_hour 資料】- {0}", dateTime);
                await powerStationRepository.AddInverterHistory(inverterHistoriesHour, inverter_history_properties);
                logger.LogInformation("【Insert InverterHistoryHour】【ArchiveInverter】【完成寫入 inverter_history_hour 資料】- {0}", dateTime);
                #endregion
            //}
        }

        private async Task ArchiveSensoravg(List<PowerStation> powerStations, string dateTime)
        {
            List<SensorAvgHistory> sensorAvgHistoryHour = new List<SensorAvgHistory>();
            foreach (var powerStation in powerStations)
            {
                try
                {
                    var sensoravg_table_name = String.Format("s{1}01_sensoravg", powerStation.SiteDB, powerStation.Code);
                    var full_sensoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, sensoravg_table_name);
                    var sensoravg_table_exist = await powerStationRepository.ExistTable(powerStation.SiteDB, sensoravg_table_name);
                    #region step2-4. 計算該電站所有sensoravg
                    try
                    {
                        if (!string.IsNullOrEmpty(sensoravg_table_exist))
                        {
                            logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
                            var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_sensoravg_table_name);
                            logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);

                            if (sensorAvgHistory != null)
                            {
                                sensorAvgHistory.PowerStationId = powerStation.Id;
                                sensorAvgHistory.TIMESTAMP = Convert.ToDateTime(sensorAvgHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");

                                sensorAvgHistoryHour.Add(sensorAvgHistory);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】【計算失敗電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】【失敗原因】- {0}", ex.Message);
                    }
                    #endregion
                }
                catch (Exception exception)
                {
                    logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveSensoravg】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
            //if (!environment.IsDevelopment())
            //{
                #region step7. 將 sensoravg INSERT 到 sensoravg_history_hour 資料表
                List<string> sensoravg_history_properties = new List<string>()
                    {
                        "PowerStationId",
                        "TIMESTAMP",
                        "SENSORAVG01",
                        "SENSORAVG02",
                        "SENSORAVG03",
                        "SENSORAVG04",
                        "SENSORAVG05",
                        "SENSORAVG06",
                        "SENSORAVG07",
                        "SENSORAVG08",
                        "SENSORAVG09",
                        "SENSORAVG10",
                        "SENSORAVG11",
                        "SENSORAVG12",
                        "SENSORAVG13",
                        "SENSORAVG14",
                        "SENSORAVG15",
                        "SENSORAVG16",
                        "SENSORAVG17",
                        "SENSORAVG18",
                        "SENSORAVG19",
                        "SENSORAVG20",
                        "SENSORAVG21",
                        "SENSORAVG22",
                        "SENSORAVG23",
                        "SENSORAVG24",
                        "SENSORAVG25",
                        "SENSORAVG26",
                        "SENSORAVG27",
                        "SENSORAVG28",
                        "SENSORAVG29",
                        "SENSORAVG30",
                        "SENSORAVG31",
                        "SENSORAVG32",
                        "SENSORAVG33",
                        "SENSORAVG34",
                        "SENSORAVG35",
                        "SENSORAVG36",
                        "SENSORAVG37",
                        "SENSORAVG38",
                        "SENSORAVG39",
                        "SENSORAVG40",
                        "SENSORAVG41",
                        "SENSORAVG42",
                        "SENSORAVG43",
                        "SENSORAVG44",
                        "SENSORAVG45",
                        "SENSORAVG46",
                        "SENSORAVG47",
                        "SENSORAVG48",
                        "SENSORAVG49",
                        "SENSORAVG50",
                    };
                logger.LogInformation("【Insert SensoravgHistoryHour】【ArchiveSensoravg】【開始寫入 sensoravg_history_hour 資料】- {0}", dateTime);
                await powerStationRepository.AddSensorAvgHistory(sensorAvgHistoryHour, sensoravg_history_properties);
                logger.LogInformation("【Insert SensoravgHistoryHour】【ArchiveSensoravg】【完成寫入 sensoravg_history_hour 資料】- {0}", dateTime);
                #endregion
            //}
        }

        private async Task ArchiveMeter(List<PowerStation> powerStations, string dateTime)
        {
            List<MeterHistory> meterHistoriesHour = new List<MeterHistory>();
            foreach (var powerStation in powerStations)
            {
                try
                {
                    var meter_table_name = String.Format("s{0}01_meter", powerStation.Code);
                    var full_meter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, meter_table_name);
                    var exist_meter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, meter_table_name);
                    #region step2-5. 計算該電站meter
                    try
                    {
                        if (string.IsNullOrEmpty(exist_meter_table))
                        {
                            logger.LogError($"【CalcPowerStationJobV2】【查無電站[{powerStation.Code}]的s{powerStation.Code}01_meter資料表】");
                        }
                        else
                        {
                            logger.LogInformation("【CalcPowerStationJobV2】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
                            var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name);
                            logger.LogInformation("【CalcPowerStationJobV2】【計算完成電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);

                            if (meterHistory != null)
                            {
                                meterHistory.PowerStationId = powerStation.Id;
                                meterHistory.TIMESTAMP = Convert.ToDateTime(meterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");

                                meterHistoriesHour.Add(meterHistory);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】【計算失敗電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】【失敗原因】- {0}", ex.Message);
                    }
                    #endregion
                }
                catch (Exception exception)
                {
                    logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveMeter】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
            //if (!environment.IsDevelopment())
            //{
                #region step8. 將 meter INSERT 到 meter_history_hour 資料表
                List<string> memter_history_properties = new List<string>()
                    {
                        "PowerStationId",
                        "TIMESTAMP",
                        "METERID",
                        "V_AB",
                        "V_BC",
                        "V_CA",
                        "I_A",
                        "I_B",
                        "I_C",
                        "I_C",
                        "P",
                        "F",
                        "INPUT_KWH",
                        "OUTPUT_KWH"
                    };
                logger.LogInformation("【Insert MeterHistoryHour】【ArchiveMeter】【開始寫入 meter_history_hour 資料】- {0}", dateTime);
                await powerStationRepository.AddMeterHistory(meterHistoriesHour, memter_history_properties);
                logger.LogInformation("【Insert MeterHistoryHour】【ArchiveMeter】【完成寫入 meter_history_hour 資料】- {0}", dateTime);
                #endregion
            //}
        }

        private async Task ArchiveWeather(List<PowerStation> powerStations, string dateTime)
        {
            Root2 observation = null;
            List<WeatherObservation> weatherObservations = new List<WeatherObservation>();
            #region 氣象觀測(取資料)
            try
            {
                logger.LogInformation("【CalcPowerStationJobV2】【開始取得氣象觀測】");
                var client = new HttpClient();
                var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP";
                HttpResponseMessage response = client.GetAsync(UVUri).Result;
                String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
                observation = JsonConvert.DeserializeObject<Root2>(jsonUVs);
                logger.LogInformation("【CalcPowerStationJobV2】【取得成功氣象觀測】");
            }
            catch (Exception ex)
            {
                logger.LogError("【CalcPowerStationJobV2】【取得失敗氣象觀測】");
                logger.LogError("【{0}】{1}", "CalcPowerStationJobV2", ex.Message);
                observation = null;
            }
            #endregion
            foreach (var powerStation in powerStations)
            {
                try
                {
                    var calcPowerStation = new PowerStation();
                    calcPowerStation.Id = powerStation.Id;
                    #region 確認是否有觀測站(沒有則新增)
                    try
                    {
                        if (powerStation.WeathersStationId == null)
                        {
                            var weatherStationId = "";
                            double shortLocation = 9999;
                            foreach (var Location in observation.Records.Location)
                            {

                                if (powerStation.Coordinate != null)
                                {
                                    var powerLocation = powerStation.Coordinate.Split(',');
                                    double p1 = Convert.ToDouble(powerLocation[0].Replace("°", string.Empty));
                                    double p2 = Convert.ToDouble(powerLocation[1].Replace("°", string.Empty));
                                    double dLat = Convert.ToDouble(Location.Lat);
                                    double dLon = Convert.ToDouble(Location.Lon);
                                    double x = Math.Pow(p1 - dLat, 2);
                                    double y = Math.Pow(p2 - dLon, 2);
                                    var nowLocation = Math.Sqrt(x + y);
                                    if (nowLocation < shortLocation)
                                    {
                                        shortLocation = nowLocation;
                                        weatherStationId = Location.StationId;
                                        calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
                                    }
                                }
                            }

                            calcPowerStation.WeathersStationId = weatherStationId;
                        }

                        WeatherObservation weatherObservation = new WeatherObservation();
                        if (powerStation.WeathersStationId != null && observation != null)
                        {
                            foreach (var Location in observation.Records.Location)
                            {
                                if (Location.StationId == powerStation.WeathersStationId)
                                {
                                    calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
                                    weatherObservation.PowerStationId = powerStation.Id;
                                    weatherObservation.Temp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
                                    weatherObservation.ObsTime = !string.IsNullOrEmpty(Location.Time.ObsTime) ? Convert.ToInt32(Location.Time.ObsTime.Substring(0, 4)) >= 1971 ? Location.Time.ObsTime : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                    calcPowerStation.WeathersStationId = powerStation.WeathersStationId;
                                    break;
                                }
                            }
                            weatherObservations.Add(weatherObservation);
                        }

                        logger.LogInformation("【CalcPowerStationJobV2】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime);
                        var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId);
                        logger.LogInformation("【CalcPowerStationJobV2】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime);
                        if (weather != null)
                        {
                            calcPowerStation.TodayWeather = weather.WeatherKey;
                            calcPowerStation.RateOfRain = weather.PoP;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveWeather】【取得失敗電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime);
                        logger.LogError("【CalcPowerStationJobV2】【ArchiveWeather】【失敗原因】- {0}", ex.Message);
                    }
                    #endregion
                }
                catch (Exception exception)
                {
                    //logger.LogError("【CalcPowerStationJobV2】[Exception] - {0}", exception.Message);
                    if (exception.InnerException != null)
                    {
                        //logger.LogError("【CalcPowerStationJobV2】[InnerException] - {0}", exception.InnerException.Message);
                    }
                }
            }
            //if (!environment.IsDevelopment())
            //{
                #region step9. 新增天氣資訊
                List<string> weather_observation_properties = new List<string>()
                    {
                        "PowerStationId",
                        "ObsTime",
                        "Temp"
                    };
                logger.LogInformation("【Insert WeatherObservation】【ArchiveWeather】【開始寫入 weather_observation 資料】- {0}", dateTime);
                await powerStationRepository.AddWeatherObservation(weatherObservations, weather_observation_properties);
                logger.LogInformation("【Insert WeatherObservation】【ArchiveWeather】【完成寫入 weather_observation 資料】- {0}", dateTime);
                #endregion
            //}
        }

    }
}
