using EVCB_OCPP20.Packet.Messages;
using EVCB_OCPP.WEBAPI.Handlers;
using EVCB_OCPP.WEBAPI.Models.WebAPI;
using EVCB_OCPP.WEBAPI.Services.Integration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using StartTransactionRequest = EVCB_OCPP.WEBAPI.Models.WebAPI.StartTransactionRequest;
using EVCB_OCPP20.Packet.DataTypes;
using EVCB_OCPP20.Packet.DataTypes.EnumTypes;
using EVCB_OCPP.Packet.Messages.SubTypes;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

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

        public OCPP201_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();
            //HttpStatusCode statusCode = StatusCodes.Status500InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {

                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

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

                if (!ChargePoint201Service.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_ocpp201(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
            {

                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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()
                {
                    Evse = Availiability.ConnectorId == 0 ? null : new EVSEType() { ConnectorId = Availiability.ConnectorId, Id = Availiability.ConnectorId },
                    OperationalStatus = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.OperationalStatusEnumType)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("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 ? 
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();


                if (!ChargePoint201Service.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 GetLogRequest()
                {
                    Log = new EVCB_OCPP20.Packet.DataTypes.LogParametersType()
                    {
                        RemoteLocation = Location.ToString(),
                        OldestTimestamp = StartTime == null ? (DateTime?)null : DateTime.SpecifyKind(DateTime.Parse(StartTime), DateTimeKind.Utc),
                        LatestTimestamp = StopTime == null ? (DateTime?)null : DateTime.SpecifyKind(DateTime.Parse(StopTime), DateTimeKind.Utc)
                    },
                    Retries = Retries == -1 ? (int?)null : Retries,
                    RetryInterval = RetryInterval == -1 ? (int?)null : RetryInterval,

                };

                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("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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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 && (ChargePoint201Service.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<Packet.Messages.SubTypes.ChargingProfileKindType>((int)StartTransaction.ChargingProfile.chargingProfileKind))
                    {
                        isvaild = false;
                    }
                    else if (StartTransaction.ChargingProfile.recurrencyKind.HasValue && !IsValidEnum<Packet.Messages.SubTypes.RecurrencyKindType>((int)StartTransaction.ChargingProfile.recurrencyKind))
                    {
                        isvaild = false;
                    }
                    else if (StartTransaction.ChargingProfile.chargingSchedule != null && !IsValidEnum<Packet.Messages.SubTypes.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 = ChargePoint201Service.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).Value;

                if (StartTransaction.ConnectorId.HasValue && ChargePoint201Service.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).HasValue &&
                    (currentStatus != Packet.Messages.SubTypes.ChargePointStatus.Available && 
                    currentStatus != Packet.Messages.SubTypes.ChargePointStatus.Reserved && currentStatus != Packet.Messages.SubTypes.ChargePointStatus.Preparing))
                {
                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                }
                else
                {
                    var _request = new RequestStartTransactionRequest()
                    {
                        EvseId = StartTransaction.ConnectorId,
                        IdToken = new IdTokenType() { IdToken = StartTransaction.IdTag, Type = EVCB_OCPP20.Packet.DataTypes.EnumTypes.IdTokenEnumType.Central },
                        RemoteStartId = (int)DateTime.UtcNow.AddYears(-100).Ticks,
                        ChargingProfile = StartTransaction.ChargingProfile == null ? null :
                        new ChargingProfileType()
                        {
                            Id = StartTransaction.ChargingProfile.chargingProfileId,
                            ChargingProfileKind = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingProfileKindEnumType)(int)StartTransaction.ChargingProfile.chargingProfileKind,
                            ChargingProfilePurpose = EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingProfilePurposeEnumType.TxProfile,
                            RecurrencyKind = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.RecurrencyKindEnumType)(int)StartTransaction.ChargingProfile.recurrencyKind,
                            StackLevel = StartTransaction.ChargingProfile.stackLevel,
                            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 ChargingScheduleType()
                            {

                                Id = StartTransaction.ChargingProfile.chargingProfileId,
                                ChargingRateUnit = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingRateUnitEnumType)(int)StartTransaction.ChargingProfile.chargingSchedule.chargingRateUnit,
                                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 (StartTransaction.ChargingProfile != null)
                    {
                        List<ChargingSchedulePeriodType> schedulePeriod = new List<ChargingSchedulePeriodType>();

                        foreach (var item in StartTransaction.ChargingProfile.chargingSchedule.chargingSchedulePeriod)
                        {
                            schedulePeriod.Add(new ChargingSchedulePeriodType()
                            {
                                Limit = item.limit,
                                StartPeriod = item.startPeriod,
                                NumberPhases = item.numberPhases

                            });
                        }
                        _request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod = schedulePeriod;
                    }


                    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, string TransactionId)
        {
            string uuid = Guid.NewGuid().ToString();
            var result = new InternalGenericResponse();
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.IsOnline(ChargeBoxId))
                {

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

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

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

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

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

                    return StatusCode(StatusCodes.Status400BadRequest, new ErrorResponse() { Code = 2105, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_CHARGING_MODE });
                }
                else
                {
                    if (ChargePoint201Service.IsTransactionRunning(ChargeBoxId, TransactionId))
                    {
                        var _request = new RequestStopTransactionRequest()
                        {
                            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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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 = ChargePoint201Service.GetChargePointCurrentSatus(ChargeBoxId, ReserveNow.ConnectorId);

                if (connectorStatus.HasValue && (connectorStatus.Value == Packet.Messages.SubTypes.ChargePointStatus.Available || connectorStatus.Value == ChargePointStatus.Preparing))
                {

                    var request = new ReserveNowRequest()
                    {
                        EvseId = ReserveNow.ConnectorId,
                        ExpiryDateTime = expiryDate,
                        IdToken = new IdTokenType() { IdToken = ReserveNow.IdTag, Type = EVCB_OCPP20.Packet.DataTypes.EnumTypes.IdTokenEnumType.Central },
                        Id = ReserveNow.ReservationId,
                        GroupIdToken = string.IsNullOrEmpty(ReserveNow.ParentIdTag) ? null : new IdTokenType() { IdToken = ReserveNow.ParentIdTag, Type = EVCB_OCPP20.Packet.DataTypes.EnumTypes.IdTokenEnumType.Central }

                    };


                    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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.IsOnline(ChargeBoxId))
                {

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

                var connectorStatus = ChargePoint201Service.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);
        }

        /// <summary>
        /// ResetEnumType 定義與1.6不同
        /// </summary>
        /// <param name="ChargeBoxId"></param>
        /// <param name="ResetType"></param>
        /// <returns></returns>
        [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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.IsOnline(ChargeBoxId))
                {

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

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

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

                    var request = new ResetRequest()
                    {
                        Type = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ResetEnumType)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("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 });
                }
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.IsOnline(ChargeBoxId))
                {

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

                var connectorStatus = ChargePoint201Service.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);
        }

        /// <summary>
        /// ChargingProfilePurposeEnumType 沒有Mapping
        /// </summary>
        /// <param name="ChargeBoxId"></param>
        /// <param name="ChargingProfile"></param>
        /// <returns></returns>
        [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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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 && ChargingProfile.ChargingProfile.recurrencyKind.HasValue && IsValidEnum<RecurrencyKindType>((int)ChargingProfile.ChargingProfile.recurrencyKind)) ||
                  !(ChargingProfile.ChargingProfile != null && ChargingProfile.ChargingProfile.recurrencyKind.HasValue && IsValidEnum<RecurrencyKindType>((int)ChargingProfile.ChargingProfile.recurrencyKind)) ||
                  !(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()
                {
                    EvseId = ChargingProfile.connectorId,
                    ChargingProfile = new ChargingProfileType()
                    {
                        Id = ChargingProfile.ChargingProfile.chargingProfileId,
                        ChargingProfileKind = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingProfileKindEnumType)(int)ChargingProfile.ChargingProfile.chargingProfileKind,
                        ChargingProfilePurpose = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingProfilePurposeEnumType)(int)ChargingProfile.ChargingProfile.chargingProfilePurpose + 1,
                        RecurrencyKind = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.RecurrencyKindEnumType)(int)ChargingProfile.ChargingProfile.recurrencyKind,
                        StackLevel = ChargingProfile.ChargingProfile.stackLevel,
                        TransactionId = ChargingProfile.ChargingProfile.SessionId.Value.ToString(),
                        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 ChargingScheduleType()
                        {

                            Id = ChargingProfile.ChargingProfile.chargingProfileId,
                            ChargingRateUnit = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingRateUnitEnumType)(int)ChargingProfile.ChargingProfile.chargingSchedule.chargingRateUnit,
                            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 (ChargingProfile.ChargingProfile.chargingSchedule.chargingSchedulePeriod != null)
                {
                    List<ChargingSchedulePeriodType> schedulePeriod = new List<ChargingSchedulePeriodType>();

                    foreach (var item in ChargingProfile.ChargingProfile.chargingSchedule.chargingSchedulePeriod)
                    {
                        schedulePeriod.Add(new ChargingSchedulePeriodType()
                        {
                            Limit = item.limit,
                            StartPeriod = item.startPeriod,
                            NumberPhases = item.numberPhases

                        });
                    }
                    request.ChargingProfile.ChargingSchedule.ChargingSchedulePeriod = schedulePeriod;
                }



                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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.IsOnline(ChargeBoxId))
                {

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

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

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

                    var request = new ClearChargingProfileRequest()
                    {
                        ChargingProfileCriteria = new ClearChargingProfileType()
                        {
                            ChargingProfilePurpose = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.ChargingProfilePurposeEnumType)(int)ChargingProfilePurpose + 1,
                            EvseId = ConnectorId == -1 ? (int?)null : (int)ConnectorId,
                            StackLevel = StackLevel == -1 ? (int?)null : (int)StackLevel,

                        },
                        ChargingProfileId = Id == -1 ? (int?)null : Id,

                    };

                    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);
        }

        /// <summary>
        /// Trigger EnumType 沒有Mapping 
        /// </summary>
        /// <param name="ChargeBoxId"></param>
        /// <param name="triggerMessage"></param>
        /// <returns></returns>
        [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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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)Packet.Messages.SubTypes.MessageTrigger.StatusNotification))
                {

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

                //create reqest

                var request = new TriggerMessageRequest()
                {
                    Evse = triggerMessage.ConnectorId is null ? null : new EVSEType() { Id = triggerMessage.ConnectorId.Value, ConnectorId = triggerMessage.ConnectorId },
                    RequestedMessage = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.MessageTriggerEnumType)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
            {
                ChargePoint201Service ChargePoint201Service = serviceProvider.GetRequiredService<ChargePoint201Service>();

                if (!ChargePoint201Service.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,
                    EvseId = 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("locallist")]
        //[Produces(typeof(ErrorResponse))]
        [Produces(typeof(InternalGenericResponse))]
        [HttpPost]
        public IActionResult SendLocalList(string ChargeBoxId, [FromBody] LocalListRequest LocalList, [FromServices] IServiceProvider serviceProvider)
        {
            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<Packet.Messages.SubTypes.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<EVCB_OCPP20.Packet.DataTypes.AuthorizationData> localAuthorizationList = new List<EVCB_OCPP20.Packet.DataTypes.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<AuthorizationStatusEnumType>((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 EVCB_OCPP20.Packet.DataTypes.AuthorizationData()
                    {
                        IdToken = new IdTokenType()
                        {
                            IdToken = LocalList.LocalAuthorizationList[i].IdTag,
                            Type = IdTokenEnumType.ISO15693
                        },
                        IdTokenInfo = LocalList.LocalAuthorizationList[i].IdTagInfo == null ? null : new IdTokenInfoType()
                        {

                            CacheExpiryDateTime = LocalList.LocalAuthorizationList[i].IdTagInfo.ExpiryDate,
                            GroupIdToken = new GroupIdTokenType()
                            {
                                IdToken = LocalList.LocalAuthorizationList[i].IdTagInfo.ParentIdTag,
                                Type = IdTokenEnumType.ISO15693
                            },
                            Status = (AuthorizationStatusEnumType)LocalList.LocalAuthorizationList[i].IdTagInfo.Status
                        }

                    });
                }

                var request = new SendLocalListRequest()
                {

                    VersionNumber = LocalList.ListVersion,
                    UpdateType = (EVCB_OCPP20.Packet.DataTypes.EnumTypes.UpdateEnumType)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("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
            {

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

                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);
        }


        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);

        }
    }
}
