using EVCB_OCPP.Domain;
using EVCB_OCPP.Domain.Models.Database;
using EVCB_OCPP.Packet.Features;
using EVCB_OCPP.Packet.Messages;
using EVCB_OCPP.Packet.Messages.SmartCharging;
using EVCB_OCPP.Packet.Messages.SubTypes;
using Newtonsoft.Json;
using OCPPServer.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EVCB_OCPP.WSServer.Message
{
    internal partial class ProfileHandler
    {


        internal void SetChargingProfile(string chargeBoxId, decimal value, ChargingRateUnitType unit)
        {
            using (var db = new MainDBContext())
            {
                var _setProfileRequest = new SetChargingProfileRequest()
                {
                    connectorId = 0,
                    csChargingProfiles = new Packet.Messages.SubTypes.csChargingProfiles()
                    {
                        chargingProfileId = 1,
                        chargingProfileKind = Packet.Messages.SubTypes.ChargingProfileKindType.Recurring,
                        chargingProfilePurpose = Packet.Messages.SubTypes.ChargingProfilePurposeType.ChargePointMaxProfile,
                        chargingSchedule = new Packet.Messages.SubTypes.ChargingSchedule()
                        {
                            chargingRateUnit = unit,
                            chargingSchedulePeriod = new List<Packet.Messages.SubTypes.ChargingSchedulePeriod>()
                                                    {
                                                        new Packet.Messages.SubTypes.ChargingSchedulePeriod(){  startPeriod=0, limit=value*1000}
                                                    },
                            duration = 60,

                        },
                        recurrencyKind = Packet.Messages.SubTypes.RecurrencyKindType.Daily,
                        stackLevel = 1,

                    }
                };

                db.ServerMessage.Add(new ServerMessage()
                {
                    ChargeBoxId = chargeBoxId,
                    CreatedBy = "Server",
                    CreatedOn = DateTime.UtcNow,
                    OutAction = _setProfileRequest.Action.ToString(),
                    OutRequest = JsonConvert.SerializeObject(_setProfileRequest, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
                    SerialNo = Guid.Empty.ToString(),
                    InMessage = string.Empty

                });
                db.SaveChanges();
            }
        }


        internal void ClearChargingProfile(string chargeBoxId)
        {
            using (var db = new MainDBContext())
            {
                var _clearProfileRequest = new ClearChargingProfileRequest()
                {
                    connectorId = 0,
                    chargingProfilePurpose = ChargingProfilePurposeType.ChargePointMaxProfile,

                };

                db.ServerMessage.Add(new ServerMessage()
                {
                    ChargeBoxId = chargeBoxId,
                    CreatedBy = "Server",
                    CreatedOn = DateTime.UtcNow,
                    OutAction = _clearProfileRequest.Action.ToString(),
                    OutRequest = JsonConvert.SerializeObject(_clearProfileRequest, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
                    SerialNo = Guid.Empty.ToString(),
                    InMessage = string.Empty

                });

                db.SaveChanges();
            }
        }





        internal MessageResult ExecuteSmartChargingConfirm(Actions action, ClientData session, IConfirmation confirm, string requestId)
        {
            MessageResult result = new MessageResult() { Success = true };

            switch (action)
            {
                case Actions.ClearChargingProfile:

                    {
                        ClearChargingProfileConfirmation _confirm = confirm as ClearChargingProfileConfirmation;
                        ClearChargingProfileRequest _request = _confirm.GetRequest() as ClearChargingProfileRequest;
                        using (var db = new MainDBContext())
                        {
                            var operation = db.MachineOperateRecord.Where(x => x.SerialNo == requestId &&
                            x.ChargeBoxId == session.ChargeBoxId && x.Status == 0).FirstOrDefault();
                            if (operation != null)
                            {
                                operation.FinishedOn = DateTime.UtcNow;
                                operation.Status = 1;//電樁有回覆
                                operation.EVSE_Status = (int)_confirm.status;//OK
                                operation.EVSE_Value = _confirm.status.ToString();
                                db.SaveChanges();
                            }

                        }
                    }
                    break;
                case Actions.SetChargingProfile:
                    {
                        SetChargingProfileConfirmation _confirm = confirm as SetChargingProfileConfirmation;
                        SetChargingProfileRequest _request = _confirm.GetRequest() as SetChargingProfileRequest;
                        using (var db = new MainDBContext())
                        {
                            var operation = db.MachineOperateRecord.Where(x => x.SerialNo == requestId &&
                            x.ChargeBoxId == session.ChargeBoxId && x.Status == 0).FirstOrDefault();
                            if (operation != null)
                            {
                                operation.FinishedOn = DateTime.UtcNow;
                                operation.Status = 1;//電樁有回覆
                                operation.EVSE_Status = (int)_confirm.status;//OK
                                operation.EVSE_Value = _confirm.status.ToString();
                                db.SaveChanges();
                            }

                        }
                    }
                    break;
                case Actions.GetCompositeSchedule:
                    {
                        GetCompositeScheduleConfirmation _confirm = confirm as GetCompositeScheduleConfirmation;
                        GetCompositeScheduleRequest _request = _confirm.GetRequest() as GetCompositeScheduleRequest;
                        using (var db = new MainDBContext())
                        {
                            var operation = db.MachineOperateRecord.Where(x => x.SerialNo == requestId &&
                            x.ChargeBoxId == session.ChargeBoxId && x.Status == 0).FirstOrDefault();
                            if (operation != null)
                            {
                                operation.FinishedOn = DateTime.UtcNow;
                                operation.Status = 1;//電樁有回覆
                                operation.EVSE_Status = (int)_confirm.status;//OK
                                operation.EVSE_Value = JsonConvert.SerializeObject(_confirm.chargingSchedule, Formatting.None);
                                db.SaveChanges();
                            }

                        }
                    }
                    break;
                default:
                    {
                        Console.WriteLine(string.Format("Not Implement {0} Logic", confirm.GetType().ToString().Replace("OCPPPackage.Messages.RemoteTrigger.", "")));
                    }
                    break;
            }
            return result;
        }


        internal MessageResult ReceivedSmartChargingError(Actions action, string errorMsg, ClientData session, string requestId)
        {
            MessageResult result = new MessageResult() { Success = true };

            switch (action)
            {
                case Actions.ClearChargingProfile:
                case Actions.SetChargingProfile:
                case Actions.GetCompositeSchedule:
                    {
                        using (var db = new MainDBContext())
                        {
                            var operation = db.MachineOperateRecord.Where(x => x.SerialNo == requestId &&
                            x.ChargeBoxId == session.ChargeBoxId && x.Status == 0).FirstOrDefault();
                            if (operation != null)
                            {
                                operation.FinishedOn = DateTime.UtcNow;
                                operation.Status = 1;//電樁有回覆
                                operation.EVSE_Status = (int)255;//錯誤
                                operation.EVSE_Value = errorMsg;
                                db.SaveChanges();
                            }

                        }
                    }
                    break;

                default:
                    {
                        Console.WriteLine(string.Format("Not Implement {0} Logic", action));
                    }
                    break;
            }
            return result;

        }
    }
}