using EVCB_OCPP.Domain.Models.Database;
using EVCB_OCPP.WSServer.Dto;
using EVCB_OCPP.WSServer.Message;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using OCPPServer.Protocol;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using EVCB_OCPP.WSServer.Service;
using Microsoft.Extensions.Logging;
using EVCB_OCPP.Domain;
using Microsoft.EntityFrameworkCore;
using EVCB_OCPP.Packet.Features;
using EVCB_OCPP.Packet.Messages.Core;

namespace EVCB_OCPP.WSServer.Jobs;

[DisallowConcurrentExecution]
public class ServerWeatherNotificationJob : IJob
{
    public ServerWeatherNotificationJob(
        ProtalServer protalServer,
        IDbContextFactory<MainDBContext> maindbContextFactory,
        ILogger<ServerWeatherNotificationJob> logger)
    {
        this.protalServer = protalServer;
        this.maindbContextFactory = maindbContextFactory;
        this.logger = logger;
    }

    private readonly ProtalServer protalServer;
    private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
    private readonly ILogger<ServerWeatherNotificationJob> logger;
    private OuterHttpClient httpClient = new OuterHttpClient();

    public async Task Execute(IJobExecutionContext context)
    {
        //logger.LogDebug("{0} Started", nameof(ServerWeatherNotificationJob));
        // Console.WriteLine("in...............ServerWeatherNotificationTrigger");
        BasicMessageHandler msgAnalyser = new BasicMessageHandler();
        Dictionary<string, ClientData> _copyClientDic = protalServer.ClientDic;
        var _CheckWeatherDt = DateTime.UtcNow;

        var locations = _copyClientDic.Where(x => !string.IsNullOrEmpty(x.Value.StationLocation)).Distinct().Select(x => x.Value.StationLocation).ToList();

        // Console.WriteLine("in...............ServerWeatherNotificationTrigger");
        foreach (var location in locations)
        {
            try
            {   //query weather
                var httpResult = await httpClient.GetWeather("https://api.weatherapi.com/v1/current.json?key=874346abc0874e69a9423510222201&q=" + location, null, null);

                string temp = "17";
                string weather_code = "1183";
                if (httpResult.Status == System.Net.HttpStatusCode.OK)
                {
                    try
                    {
                        var jsonResult = JsonConvert.DeserializeObject(httpResult.Response) as JObject;
                        temp = jsonResult["current"]["temp_c"].ToString();
                        weather_code = jsonResult["current"]["condition"]["code"].ToString();


                    }
                    catch (Exception ex)
                    {
                        ;
                    }

                }

                #region 台泥氣象Mapping
                switch (weather_code)
                {
                    case "1000":
                        weather_code = "1";
                        break;
                    case "1003":
                    case "1006":
                    case "1009":
                        weather_code = "2";
                        break;
                    case "1063":
                    case "1072":
                    case "1150":
                    case "1153":
                    case "1168":
                    case "1171":
                    case "1180":
                    case "1183":
                    case "1186":
                    case "1189":
                    case "1192":
                    case "1195":
                    case "1198":
                    case "1201":
                    case "1237":
                    case "1240":
                    case "1243":
                    case "1246":
                    case "1261":
                    case "1264":
                        weather_code = "3";
                        break;
                    case "1087":
                    case "1273":
                    case "1276":
                    case "1279":
                    case "1282":
                        weather_code = "4";
                        break;
                    case "1066":
                    case "1069":
                    case "1114":
                    case "1117":
                    case "1204":
                    case "1207":
                    case "1210":
                    case "1213":
                    case "1216":
                    case "1219":
                    case "1222":
                    case "1225":
                    case "1249":
                    case "1252":
                    case "1255":
                    case "1258":
                        weather_code = "5";
                        break;
                    case "1030":
                    case "1135":
                    case "1147":
                        weather_code = "2";
                        break;
                    default:
                        weather_code = "2";
                        break;
                }
                #endregion


                if (protalServer.TCCStationDic.ContainsKey(location))
                {
                    protalServer.TCCStationDic[location].Temperature = (int)double.Parse(temp);
                    protalServer.TCCStationDic[location].WeatherID = int.Parse(weather_code);
                }
                else
                {
                    protalServer.TCCStationDic.Add(location, new TCCWeatherDto() { WeatherID = int.Parse(weather_code), Temperature = (int)double.Parse(temp) });
                }

            }
            catch (Exception ex)
            {
                logger.LogError("ServerWeatherNotificationTrigger ChargeBoxId:{0}  Ex:{1}", location, ex.ToString());
            }
        }

        var clients = _copyClientDic.Where(x => x.Value.CustomerId == new Guid("009E603C-79CD-4620-A2B8-D9349C0E8AD8")).
        Select(x => new { ChargeBoxId = x.Value.ChargeBoxId, StationLocation = x.Value.StationLocation }).ToList();

        using (var db = maindbContextFactory.CreateDbContext())
        {

            foreach (var client in clients)
            {
                try
                {
                    if (string.IsNullOrEmpty(client.StationLocation))
                    {
                        Console.WriteLine(client.StationLocation + " is empty");
                        continue;
                    }


                    if (protalServer.TCCStationDic.ContainsKey(client.StationLocation))
                    {
                        db.ServerMessage.Add(new ServerMessage()
                        {
                            ChargeBoxId = client.ChargeBoxId,
                            CreatedBy = "Server",
                            CreatedOn = DateTime.UtcNow,
                            OutAction = Actions.DataTransfer.ToString(),
                            OutRequest = JsonConvert.SerializeObject(
                                               new DataTransferRequest()
                                               {
                                                   messageId = "ID_Weather_Info",
                                                   vendorId = "Phihong Technology",
                                                   data = JsonConvert.SerializeObject(
                                                       new
                                                       {
                                                           weatherId = protalServer.TCCStationDic[client.StationLocation].WeatherID,
                                                           Temperature = protalServer.TCCStationDic[client.StationLocation].Temperature
                                                       })
                                               },
                                               new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
                            SerialNo = Guid.NewGuid().ToString(),
                            InMessage = string.Empty

                        });

                        db.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError("ServerWeatherNotificationTrigger ChargeBoxId:{0}  Ex:{1}", client.ChargeBoxId, ex.ToString());
                }
            }
        }
    }
}
