using EVCB_OCPP.Packet.Messages;
using EVCB_OCPP.Packet.Messages.Core;
using EVCB_OCPP.Packet.Messages.FirmwareManagement;
using EVCB_OCPP.Packet.Messages.LocalAuthListManagement;
using EVCB_OCPP.Packet.Messages.RemoteTrigger;
using EVCB_OCPP.Packet.Messages.Reservation;
using EVCB_OCPP.Packet.Messages.SmartCharging;
using EVCB_OCPP.Packet.Messages.SubTypes;
using EVCB_OCPP.WEBAPI.Handlers;
using EVCB_OCPP.WEBAPI.Models.WebAPI;
using EVCB_OCPP.WEBAPI.Services;
using EVCB_OCPP.WEBAPI.Services.Integration;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Http;
using Internal_Actions = EVCB_OCPP.WEBAPI.Services.Integration.Internal_Actions;
using ServerTriggerService = EVCB_OCPP.WEBAPI.Services.Integration.ServerTriggerService;
using StartTransactionRequest = EVCB_OCPP.WEBAPI.Models.WebAPI.StartTransactionRequest;

namespace EVCB_OCPP.WEBAPI.Controllers.Version2.ocpp16
{
    [ApiExplorerSettings(IgnoreApi = false)]
    [Route("api/v2/ocpp16")]
    //[InernalAuthentication]
    [ServiceFilter(typeof(InernalAuthentication))]
    public class OCPP16_InternalController : ControllerBase
    {
        private readonly IServiceProvider serviceProvider;

        public OCPP16_InternalController(IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider;
        }

        [Route("command")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpGet]
        public IActionResult CommandofExecution(int OrderNo, string SerialNo, string ChargeBoxId)
        {

            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!IsValidEnum<Internal_Actions>(OrderNo) || string.IsNullOrEmpty(ChargeBoxId))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                if (!chargePointService.Exists(ChargeBoxId))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                ServerTriggerService triggerService = serviceProvider.GetRequiredService<ServerTriggerService>();
                var excution = triggerService.GetExecution(SerialNo, (Internal_Actions)OrderNo, ChargeBoxId);

                if (excution == null)
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2102, Message = EVCBConfiguration.ERROR_MSG_DATA_NOTFOUND });
                }

                result.Message = JsonConvert.SerializeObject(excution, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                statusCode = StatusCodes.Status200OK;

            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "CommandofExecution", ex.ToString())
                });
            }

            return StatusCode(statusCode, result);
        }

        [Route("availability")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPut]
        public IActionResult Availability(string ChargeBoxId, [FromBody] AvailiabilityRequest Availiability)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (Availiability == null ||
                    !(Availiability.ConnectorId >= 0) ||
                    !(Availiability.AvailabilityType > 0 && Availiability.AvailabilityType < 3))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest

                var request = new ChangeAvailabilityRequest()
                {
                    connectorId = Availiability.ConnectorId,
                    type = (EVCB_OCPP.Packet.Messages.SubTypes.AvailabilityType)Availiability.AvailabilityType
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "Availability", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }


        [Route("configuration")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPut]
        public IActionResult ChargeBoxConfiguration(string ChargeBoxId, [FromBody] SingleConfigurationRequest SingleConfiguration)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                //Does charge exist ? 
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();


                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (SingleConfiguration == null ||
                    (string.IsNullOrEmpty(SingleConfiguration.Key) || string.IsNullOrEmpty(SingleConfiguration.Value)))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest
                var request = new ChangeConfigurationRequest()
                {
                    key = SingleConfiguration.Key,
                    value = SingleConfiguration.Value
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;
            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "ChangeConfiguration", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }

        [Route("configuration")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpGet]
        public IActionResult ChargeBoxConfiguration(string ChargeBoxId, string Keys)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                //Does charge exist ? 
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (string.IsNullOrEmpty(Keys) || Keys.Split('/').Count() > 20)
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest
                var request = new GetConfigurationRequest()
                {
                    key = Keys.Split('/').ToList()
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;
            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "GetConfiguration", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }

        [Route("diagnostics")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpGet]
        public IActionResult Diagnostics(string ChargeBoxId, Uri Location, int Retries = -1, int RetryInterval = -1, string StartTime = null, string StopTime = null)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                //Does charge exist ? 
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();


                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                DateTime vaildtime = new DateTime();
                if (!Location.IsWellFormedOriginalString()
                    || (!string.IsNullOrEmpty(StartTime) && !DateTime.TryParse(StartTime, out vaildtime))
                    || (!string.IsNullOrEmpty(StopTime) && !DateTime.TryParse(StopTime, out vaildtime)))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest
                var request = new GetDiagnosticsRequest()
                {
                    location = Location,
                    retries = Retries == -1 ? (int?)null : Retries,
                    retryInterval = RetryInterval == -1 ? (int?)null : RetryInterval,
                    startTime = StartTime == null ? (DateTime?)null : DateTime.SpecifyKind(DateTime.Parse(StartTime), DateTimeKind.Utc),
                    stopTime = StopTime == null ? (DateTime?)null : DateTime.SpecifyKind(DateTime.Parse(StopTime), DateTimeKind.Utc)

                };

                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "GetDiagonostics", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }


        [Route("locallistversion")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpGet]
        public IActionResult Locallistversion(string ChargeBoxId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                if (!AddCommandtoServer(ChargeBoxId, uuid, new GetLocalListVersionRequest()))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "GetLocallistversion", ex.ToString())

                });


            }

            return StatusCode(statusCode, result);
        }

        [Route("transaction")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult StartTransaction(string ChargeBoxId, [FromBody] StartTransactionRequest StartTransaction)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter


                if (StartTransaction == null || !StartTransaction.ConnectorId.HasValue
                    || (StartTransaction.ConnectorId.HasValue && (chargePointService.GetNumberofConnectors(ChargeBoxId) < StartTransaction.ConnectorId || StartTransaction.ConnectorId < 0)) || string.IsNullOrEmpty(StartTransaction.IdTag) || StartTransaction.IdTag.Length > 20)
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                if (StartTransaction.ChargingProfile != null)
                {
                    bool isvaild = true;
                    if (!IsValidEnum<ChargingProfileKindType>((int)StartTransaction.ChargingProfile.chargingProfileKind))
                    {
                        isvaild = false;
                    }
                    else if (StartTransaction.ChargingProfile.recurrencyKind.HasValue && !IsValidEnum<RecurrencyKindType>((int)StartTransaction.ChargingProfile.recurrencyKind))
                    {
                        isvaild = false;
                    }
                    else if (StartTransaction.ChargingProfile.chargingSchedule != null && !IsValidEnum<ChargingRateUnitType>((int)StartTransaction.ChargingProfile.chargingSchedule.chargingRateUnit))
                    {
                        isvaild = false;
                    }
                    else
                    {

                        //do nothing
                    }
                    if (!isvaild)
                    {
                        return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });

                    }

                }

                var currentStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).Value;

                if (StartTransaction.ConnectorId.HasValue && chargePointService.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).HasValue &&
                    (currentStatus != ChargePointStatus.Available && currentStatus != ChargePointStatus.Reserved && currentStatus != ChargePointStatus.Preparing))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }
                else
                {
                    var _request = new RemoteStartTransactionRequest()
                    {
                        connectorId = StartTransaction.ConnectorId,
                        idTag = StartTransaction.IdTag,
                        chargingProfile = StartTransaction.ChargingProfile == null ? null :
                         new csChargingProfiles()
                         {
                             chargingProfileId = StartTransaction.ChargingProfile.chargingProfileId,
                             stackLevel = StartTransaction.ChargingProfile.stackLevel,
                             chargingProfilePurpose = ChargingProfilePurposeType.TxProfile,
                             chargingProfileKind = StartTransaction.ChargingProfile.chargingProfileKind,
                             recurrencyKind = StartTransaction.ChargingProfile.recurrencyKind,
                             validFrom = StartTransaction.ChargingProfile.validFrom == null ? (DateTime?)null : DateTime.SpecifyKind(StartTransaction.ChargingProfile.validFrom.Value, DateTimeKind.Utc),
                             validTo = StartTransaction.ChargingProfile.validTo == null ? (DateTime?)null : DateTime.SpecifyKind(StartTransaction.ChargingProfile.validTo.Value, DateTimeKind.Utc),
                             chargingSchedule = new ChargingSchedule()
                             {
                                 chargingRateUnit = StartTransaction.ChargingProfile.chargingSchedule.chargingRateUnit,
                                 chargingSchedulePeriod = StartTransaction.ChargingProfile.chargingSchedule.chargingSchedulePeriod,
                                 duration = StartTransaction.ChargingProfile.chargingSchedule.duration,
                                 minChargingRate = StartTransaction.ChargingProfile.chargingSchedule.minChargingRate,
                                 startSchedule = StartTransaction.ChargingProfile.chargingSchedule.startSchedule == null ? (DateTime?)null : DateTime.SpecifyKind(StartTransaction.ChargingProfile.chargingSchedule.startSchedule.Value, DateTimeKind.Utc)
                             }
                         }

                    };


                    if (!AddCommandtoServer(ChargeBoxId, uuid, _request))
                    {
                        throw new Exception("Write Command Fail!!");
                    }
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "StartTransaction", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("transaction")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPut]
        public IActionResult StopTransaction(string ChargeBoxId, int TransactionId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var _ConnectorId = chargePointService.GetConnectorwithOngoingTransaction(ChargeBoxId, TransactionId);

                if (_ConnectorId == -1)
                {
                    // 充完電 & 這個充電序不存在
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2106, Message = EVCBConfiguration.ERROR_MSG_TX_FINISHED_OR_NOTFOUND });
                }

                var _ConnectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, _ConnectorId);

                if (!(_ConnectorStatus.HasValue && _ConnectorStatus == ChargePointStatus.Charging || _ConnectorStatus == ChargePointStatus.SuspendedEVSE || _ConnectorStatus == ChargePointStatus.SuspendedEV))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2105, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_CHARGING_MODE });
                }
                else
                {
                    if (chargePointService.IsTransactionRunning(ChargeBoxId, TransactionId))
                    {
                        var _request = new RemoteStopTransactionRequest()
                        {
                            transactionId = TransactionId
                        };

                        //下發停止
                        if (!AddCommandtoServer(ChargeBoxId, uuid, _request))
                        {
                            throw new Exception("Write Command Fail!!");
                        }
                    }
                    else
                    {
                        return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2104, Message = EVCBConfiguration.ERROR_MSG_SESSION_WAS_FINISHED });
                    }
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;
                return StatusCode(statusCode, result);

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "StopTransaction", ex.ToString())

                });


            }


        }

        [Route("reservation")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult ReserveNow(string ChargeBoxId, [FromBody] ReserveRequest ReserveNow)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }


                DateTime expiryDate = new DateTime();
                //check parameter
                if (ReserveNow == null ||
                    !(ReserveNow.ConnectorId >= 0) ||
                    string.IsNullOrEmpty(ReserveNow.IdTag) ||
                    ReserveNow.ReservationId == -1 ||
                    !DateTime.TryParse(ReserveNow.ExpiryDate, out expiryDate))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                expiryDate = DateTime.SpecifyKind(DateTime.Parse(ReserveNow.ExpiryDate), DateTimeKind.Utc);

                if (DateTime.Compare(DateTime.UtcNow, expiryDate) >= 0)
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                var connectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, ReserveNow.ConnectorId);

                if (connectorStatus.HasValue && (connectorStatus.Value == ChargePointStatus.Available || connectorStatus.Value == ChargePointStatus.Preparing))
                {
                    //create reqest

                    var request = new ReserveNowRequest()
                    {
                        connectorId = ReserveNow.ConnectorId,
                        expiryDate = expiryDate,
                        idTag = ReserveNow.IdTag,
                        reservationId = ReserveNow.ReservationId,
                        parentIdTag = ReserveNow.ParentIdTag

                    };


                    if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                    {
                        throw new Exception("Write Command Fail!!");
                    }

                    statusCode = StatusCodes.Status200OK;
                    result.SerialNo = uuid;
                }
                else
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }



            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "ReserveNow", ex.ToString())

                });



            }

            return StatusCode(statusCode, result);
        }

        [Route("reservation")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpDelete]
        public IActionResult CancelResrvation(string ChargeBoxId, int ReservationId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var connectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, 0);

                if (connectorStatus.HasValue && connectorStatus.Value == ChargePointStatus.Available)
                {
                    //create reqest

                    var request = new CancelReservationRequest()
                    {
                        reservationId = ReservationId

                    };

                    if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                    {
                        throw new Exception("Write Command Fail!!");
                    }

                    statusCode = StatusCodes.Status200OK;
                    result.SerialNo = uuid;
                }
                else
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }


            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "CancelResrvation", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("reset")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult Reset(string ChargeBoxId, int ResetType)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var connectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, 0);

                if (connectorStatus.HasValue && connectorStatus.Value == ChargePointStatus.Available)
                {
                    //create reqest

                    var request = new ResetRequest()
                    {
                        type = (Packet.Messages.SubTypes.ResetType)ResetType

                    };

                    if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                    {
                        throw new Exception("Write Command Fail!!");
                    }

                    statusCode = StatusCodes.Status200OK;
                    result.SerialNo = uuid;
                }
                else
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }


            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "Reset", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("locallist")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult SendLocalList(string ChargeBoxId, [FromBody] LocalListRequest LocalList)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (LocalList == null ||
                    !IsValidEnum<UpdateType>((int)LocalList.UpdateType) || LocalList.LocalAuthorizationList == null
                    || (LocalList.LocalAuthorizationList != null && LocalList.LocalAuthorizationList.Count == 0))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                bool badRequest = false;
                List<AuthorizationData> localAuthorizationList = new List<AuthorizationData>();
                for (int i = 0; i < LocalList.LocalAuthorizationList.Count; i++)
                {
                    if (string.IsNullOrEmpty(LocalList.LocalAuthorizationList[i].IdTag))
                        badRequest = true;

                    if (LocalList.LocalAuthorizationList[i].IdTagInfo != null && !IsValidEnum<AuthorizationStatus>((int)LocalList.LocalAuthorizationList[i].IdTagInfo.Status))
                        badRequest = true;

                    if (badRequest)
                    {
                        return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                    }
                    localAuthorizationList.Add(new AuthorizationData()
                    {
                        idTag = LocalList.LocalAuthorizationList[i].IdTag,
                        idTagInfo = LocalList.LocalAuthorizationList[i].IdTagInfo == null ? null :
                              new IdTagInfo()
                              {
                                  expiryDate = LocalList.LocalAuthorizationList[i].IdTagInfo.ExpiryDate,
                                  parentIdTag = LocalList.LocalAuthorizationList[i].IdTagInfo.ParentIdTag,
                                  status = LocalList.LocalAuthorizationList[i].IdTagInfo.Status
                              }
                    });
                }

                var request = new SendLocalListRequest()
                {
                    listVersion = LocalList.ListVersion,
                    updateType = (UpdateType)LocalList.UpdateType,
                    localAuthorizationList = localAuthorizationList

                };

                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "SendLocalList", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("datatransfer")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult SendDataTransfer(string ChargeBoxId, string VenderId, [FromBody] string Data, string MessageId = "")
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                if (string.IsNullOrEmpty(ChargeBoxId) || string.IsNullOrEmpty(VenderId))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var request = new DataTransferRequest()
                {
                    data = Data,
                    messageId = MessageId,
                    vendorId = VenderId
                };

                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }


                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;
            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "SendDataTransfer", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }


        [Route("cache")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpDelete]
        public IActionResult ClearCache(string ChargeBoxId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var connectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, 0);

                if (connectorStatus.HasValue && connectorStatus.Value == ChargePointStatus.Available)
                {

                    if (!AddCommandtoServer(ChargeBoxId, uuid, new ClearCacheRequest()))
                    {
                        throw new Exception("Write Command Fail!!");
                    }

                    statusCode = StatusCodes.Status200OK;
                    result.SerialNo = uuid;
                }
                else
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }


            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "ClearCache", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("chargingprofile")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult SetChargingProfile(string ChargeBoxId, [FromBody] ChargingProfileRequest ChargingProfile)
        {


            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (ChargingProfile == null ||
                    ChargingProfile.connectorId < 0 ||
                  !(ChargingProfile.ChargingProfile != null && IsValidEnum<ChargingProfileKindType>((int)ChargingProfile.ChargingProfile.chargingProfileKind)) ||
                 !(ChargingProfile.ChargingProfile != null && IsValidEnum<ChargingProfilePurposeType>((int)ChargingProfile.ChargingProfile.chargingProfilePurpose)) ||
                  !(ChargingProfile.ChargingProfile != null && ChargingProfile.ChargingProfile.chargingSchedule != null && IsValidEnum<ChargingRateUnitType>((int)ChargingProfile.ChargingProfile.chargingSchedule.chargingRateUnit)))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                if (ChargingProfile.ChargingProfile.chargingSchedule.chargingSchedulePeriod.Count == 0)
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                var request = new SetChargingProfileRequest()
                {
                    connectorId = ChargingProfile.connectorId,
                    csChargingProfiles = new csChargingProfiles()
                    {
                        chargingProfileId = ChargingProfile.ChargingProfile.chargingProfileId,
                        chargingProfileKind = ChargingProfile.ChargingProfile.chargingProfileKind,
                        chargingProfilePurpose = ChargingProfile.ChargingProfile.chargingProfilePurpose,
                        recurrencyKind = ChargingProfile.ChargingProfile.recurrencyKind,
                        stackLevel = ChargingProfile.ChargingProfile.stackLevel,
                        transactionId = ChargingProfile.ChargingProfile.SessionId,
                        validFrom = ChargingProfile.ChargingProfile.validFrom == null ? (DateTime?)null : DateTime.SpecifyKind(ChargingProfile.ChargingProfile.validFrom.Value, DateTimeKind.Utc),
                        validTo = ChargingProfile.ChargingProfile.validTo == null ? (DateTime?)null : DateTime.SpecifyKind(ChargingProfile.ChargingProfile.validTo.Value, DateTimeKind.Utc),
                        chargingSchedule = new ChargingSchedule()
                        {
                            chargingRateUnit = ChargingProfile.ChargingProfile.chargingSchedule.chargingRateUnit,
                            chargingSchedulePeriod = ChargingProfile.ChargingProfile.chargingSchedule.chargingSchedulePeriod,
                            duration = ChargingProfile.ChargingProfile.chargingSchedule.duration,
                            minChargingRate = ChargingProfile.ChargingProfile.chargingSchedule.minChargingRate,
                            startSchedule = ChargingProfile.ChargingProfile.chargingSchedule.startSchedule == null ? (DateTime?)null : DateTime.SpecifyKind(ChargingProfile.ChargingProfile.chargingSchedule.startSchedule.Value, DateTimeKind.Utc)
                        }
                    }
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }


                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {

                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "SetChargingProfile", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }

        [Route("chargingprofile")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpDelete]
        public IActionResult ClearChargingProfile(string ChargeBoxId, int Id = -1, int ConnectorId = -1, int ChargingProfilePurpose = -1, int StackLevel = -1)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                var connectorStatus = chargePointService.GetChargePointCurrentSatus(ChargeBoxId, 0);

                if (connectorStatus.HasValue && connectorStatus.Value == ChargePointStatus.Available)
                {

                    var request = new ClearChargingProfileRequest()
                    {
                        chargingProfilePurpose = ChargingProfilePurpose == -1 ? (ChargingProfilePurposeType?)null : (ChargingProfilePurposeType)ChargingProfilePurpose,
                        connectorId = ConnectorId == -1 ? (int?)null : (int)ConnectorId,
                        id = Id == -1 ? (int?)null : (int)ChargingProfilePurpose,
                        stackLevel = StackLevel == -1 ? (int?)null : (int)StackLevel
                    };

                    if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                    {
                        throw new Exception("Write Command Fail!!");
                    }

                    statusCode = StatusCodes.Status200OK;
                    result.SerialNo = uuid;
                }
                else
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }


            }
            catch (Exception ex)
            {


                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "ClearChargingProfile", ex.ToString())

                });
            }

            return StatusCode(statusCode, result);
        }

        [Route("trigger")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult TriggerMessage(string ChargeBoxId, [FromBody] TriggerRequest triggerMessage)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (triggerMessage == null || !(triggerMessage.TriggerType >= 1 && triggerMessage.TriggerType <= (int)MessageTrigger.StatusNotification))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest

                var request = new TriggerMessageRequest()
                {
                    connectorId = triggerMessage.ConnectorId == -1 ? (int?)null : triggerMessage.ConnectorId,
                    requestedMessage = (MessageTrigger)triggerMessage.TriggerType
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "TriggerMessage", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }

        [Route("unlockconnector")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult UnlockConnector(string ChargeBoxId, int ConnectorId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (ConnectorId < 0)
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                //create reqest

                var request = new UnlockConnectorRequest()
                {
                    connectorId = ConnectorId
                };


                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "UnlockConnector", ex.ToString())

                });


            }

            return StatusCode(statusCode, result);
        }


        [Route("compositeschedule")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpGet]
        public IActionResult CompositeSchedule(string ChargeBoxId, int ConnectorId, int Duration, int ChargingRateUnit = -1)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                ChargePoint16Service chargePointService = serviceProvider.GetRequiredService<ChargePoint16Service>();

                if (!chargePointService.IsOnline(ChargeBoxId))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2101, Message = EVCBConfiguration.ERROR_MSG_CHARGEBOXID_ISNT_EXIST_OR_OFFLINE });
                }

                //check parameter
                if (!(ConnectorId >= 0) || !(Duration > 0))
                {

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                if ((ChargingRateUnit != -1 && (ChargingRateUnit <= 0 || ChargingRateUnit >= 3)))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2100, Message = EVCBConfiguration.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT });
                }

                var request = new GetCompositeScheduleRequest()
                {
                    connectorId = ConnectorId,
                    duration = Duration,
                    chargingRateUnit = ChargingRateUnit > 0 ? (ChargingRateUnitType)ChargingRateUnit : (ChargingRateUnitType?)null
                };

                if (!AddCommandtoServer(ChargeBoxId, uuid, request))
                {
                    throw new Exception("Write Command Fail!!");
                }

                statusCode = StatusCodes.Status200OK;
                result.SerialNo = uuid;

            }
            catch (Exception ex)
            {
                return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse()
                {
                    Code = 2999,
                    Message = EVCBConfiguration.ERROR_MSG_UNEXPECTEDERROR,
                    ErrorDetail = string.Format(EVCBConfiguration.ERRORMESSAGE_FORMAT, "CompositeSchedule", ex.ToString())

                });

            }

            return StatusCode(statusCode, result);
        }


        private bool AddCommandtoServer(string chargeBoxId, string uuid, IRequest request)
        {
            bool result = false;
            try
            {
                ServerTriggerService service = serviceProvider.GetRequiredService<ServerTriggerService>();
                service.AddMessage(chargeBoxId, uuid, request);
                result = true;
            }
            catch (Exception ex)
            {
                ;
            }

            return result;
        }


        private bool IsValidEnum<TEnum>(int enumValue)
        {

            return Enum.IsDefined(typeof(TEnum), enumValue);

        }

    }
}
