using Dapper;
using EVCB_OCPP.Packet.Messages.SubTypes;
using EVCB_OCPP.WEBAPI.Handlers;
using EVCB_OCPP.WEBAPI.Models;
using EVCB_OCPP.WEBAPI.Models.WebAPI;
using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
using EVCB_OCPP.WEBAPI.Services;
using EVCB_OCPP.WEBAPI.Services.Integration;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using ChargingStationService = EVCB_OCPP.WEBAPI.Services.Integration.ChargingStationService;
using CommandType = EVCB_OCPP.WEBAPI.Models.WebAPI.Dto.CommandType;
using IChargePointService = EVCB_OCPP.WEBAPI.Services.Integration.IChargePointService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Data.SqlClient;
using EVCB_OCPP.WEBAPI.Helpers;
using EVCB_OCPP.Domain;

namespace EVCB_OCPP.WEBAPI.Controllers.Version2
{

    [ApiExplorerSettings(IgnoreApi = false)]
    [Route("api/v2/cpo")]
    [ServiceFilter(typeof(CPOAuthentication))]
    public class V2_CPOController : ControllerBase
    {
        private readonly IServiceProvider serviceProvider;

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

        [Route("information")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult BasicInformationofEVSEs(int? Limit = -1, int StationId = -1, string ChargeBoxId = "", DateTime? DateFrom = null, DateTime? DateTo = null, int? Offset = 0)
        {

            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {


                if (Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId))
                {
                    var _customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();

                    var _innerResponse = new { EVSEs = new List<EVSE>() };
                    ChargingStationService _stationService = serviceProvider.GetRequiredService<ChargingStationService>();

                    if (StationId > -1)
                    {
                        if (_stationService.ContainsStation(_customerId, StationId))
                        {
                            if (DateTo.HasValue)
                            {
                                if (!DateFrom.HasValue)
                                {

                                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT;
                                    result.StatusCode = (int)CPO_StatusCode.PARAMETER_OUTOFRANGE_INCORRECT;
                                    //statusCode = HttpStatusCode.BadRequest;
                                    statusCode = StatusCodes.Status400BadRequest;
                                    return StatusCode(statusCode, result);
                                }
                            }
                            _innerResponse = new { EVSEs = _stationService.GetEVSEsbyStationId(StationId, DateFrom, DateTo, Offset.Value, Limit == -1 ? 1000 : Limit.Value) };


                        }
                    }
                    else
                    {
                        IChargePointService _service = null;
                        if (GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16)
                        {
                            _service = serviceProvider.GetRequiredService<ChargePoint16Service>();
                        }
                        else
                        {
                            _service = serviceProvider.GetRequiredService<ChargePoint201Service>();
                        }
                        _innerResponse = new { EVSEs = new List<EVSE>() };
                        _innerResponse.EVSEs.Add(_service.GetEVSEsbyChargeBoxId(ChargeBoxId, DateFrom, DateTo));


                    }

                    result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;

                }
                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }


        }

        [Route("contact_information")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult ContactInformation([FromServices]SqlConnectionFactory<MainDBContext> mainDbConnectionFactory)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                if (Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId))
                {
                    var customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();
                    // mainConnectionString = configuration.GetConnectionString("MainDBContext");
                    var parameters = new DynamicParameters();
                    parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input);
                    string hotline = string.Empty;
                    using (SqlConnection conn = mainDbConnectionFactory.Create())
                    {
                        string strSql = "SELECT [Hotline]  FROM [dbo].[Customer] where Id=@CustomerId; ";
                        hotline = conn.ExecuteScalar<string>(strSql, parameters);
                    }
                    result.Data = JsonConvert.SerializeObject(new { Info = hotline }, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                result.StatusCode = (int)CPO_StatusCode.Success;
                result.StatusMessage = CPO_StatusMessage.Success;


                //statusCode = HttpStatusCode.OK;
                statusCode = StatusCodes.Status200OK;
                return StatusCode(statusCode, result);

            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

        }

        [Route("stationInfo")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public async Task<IActionResult> StationInfo(string ChargeBoxId)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;

            try
            {
                ChargingStationService service = serviceProvider.GetRequiredService<ChargingStationService>();

                var _innerData = await service.GetInfobyChargeBoxIdAsync(ChargeBoxId);

                if (_innerData is null)
                {
                    result.StatusCode = (int)CPO_StatusCode.CANT_FOUND_DATA;
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_SESSIONDETAIL;
                    //statusCode = HttpStatusCode.NotFound;
                    statusCode = StatusCodes.Status404NotFound;
                    return StatusCode(statusCode, result);
                }

                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                result.StatusCode = (int)CPO_StatusCode.Success;
                result.StatusMessage = CPO_StatusMessage.Success;
                //statusCode = HttpStatusCode.OK;
                statusCode = StatusCodes.Status200OK;
                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

        }

        [Route("version")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult Version(string ChargeBoxId)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;

            try
            {
                IChargePointService _service = null;
                if (GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16)
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint16Service>();
                }
                else
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint201Service>();
                }

                result.Data = _service.GetVersionbyChargeBoxId(ChargeBoxId);
                result.StatusCode = (int)CPO_StatusCode.Success;
                result.StatusMessage = CPO_StatusMessage.Success;
                //statusCode = HttpStatusCode.OK;
                statusCode = StatusCodes.Status200OK;
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);

        }

        [Route("station")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult Station()
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            try
            {
                if (Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId))
                {
                    var _customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();
                    ChargingStationService _service = serviceProvider.GetRequiredService<ChargingStationService>();
                    var _innerResponse = new { Stations = _service.GetStationsbyCustomerId(_customerId) };
                    result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }
        }


        [Route("commands/start_session")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpPost]
        async public Task<IActionResult> StartSession([FromBody] StartSessionRequest request)
        {

            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(request.ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }

                IChargePointService _service = null;
                if (GetChargePointOCPPProtocol(request.ChargeBoxId) == OCPPProtocolType.OCPP16)
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint16Service>();
                }
                else
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint201Service>();
                }

                if (!string.IsNullOrEmpty(request.ChargeBoxId) && request.ChargeBoxId.Length <= 25 && (!request.ConnectorId.HasValue
               || (_service.GetNumberofConnectors(request.ChargeBoxId) >= request.ConnectorId && request.ConnectorId > 0))
                && !string.IsNullOrEmpty(request.Token) && request.Token.Length <= 20)
                {

                    InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                    ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                    //trigger to charge
                    var _request = new Models.WebAPI.StartTransactionRequest()
                    {
                        ConnectorId = request.ConnectorId,
                        IdTag = request.Token
                    };

                    string urlformat = "{0}://{1}";
                    string ocppProtocol = GetChargePointOCPPProtocol(request.ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";

                    var _innerResult = await _client.Post(
                        string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent()),
                        $"/api/v1/ocpp{ocppProtocol}/transaction?ChargeBoxId={request.ChargeBoxId}",
                        new Dictionary<string, string>()
                        {
                            { "PartnerId",_CustomerId}

                        },
                        _request, 
                        _customer.GetAPIKey(new Guid(_CustomerId)));


                    _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                    result = GetErrorDescription(_innerResult);
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);

                    if (_innerResult.Status == HttpStatusCode.InternalServerError)
                    {

                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.InternalServerError;
                        statusCode = StatusCodes.Status500InternalServerError;
                    }
                    else
                    {
                        result.SerialNo = _innerResult.SerialNo;
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.OK;
                        statusCode = StatusCodes.Status200OK;
                    }

                }
                else
                {
                    // 參數不符合定義
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT;
                    result.StatusCode = (int)CPO_StatusCode.PARAMETER_OUTOFRANGE_INCORRECT;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                }


                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }


        }


        [Route("commands/stop_session")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpPost]
        async public Task<IActionResult> StopSession(string ChargeBoxId, int SessionId)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;//.BadRequest;
                    return StatusCode(statusCode, result);
                }

                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                string urlformat = "{0}://{1}";
                string ocppProtocol = GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";

                var _innerResult = await _client.Put(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent(), ocppProtocol, ChargeBoxId, SessionId), 
                    $"/api/v1/ocpp{ocppProtocol}/transaction?ChargeBoxId={ChargeBoxId}&TransactionId={SessionId}",
                    new Dictionary<string, string>()
                    {
                        { "PartnerId",_CustomerId}

                    }, null, _customer.GetAPIKey(new Guid(_CustomerId)));


                _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                result = GetErrorDescription(_innerResult);
                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                if (_innerResult.Success)
                {
                    result.SerialNo = _innerResult.SerialNo;
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                else
                {
                    if (_innerResult.ErrorCode == (int)CPO_StatusCode.UnexpectedError)
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                    else
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                }


            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("commands/reserve_now")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpPost]
        async public Task<IActionResult> ReserveNow([FromBody] ReserveNowRequest request)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(request.ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }


                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                string urlformat = "{0}://{1}";
                string ocppProtocol = GetChargePointOCPPProtocol(request.ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";

                var _innerRequest = new ReserveRequest()
                {
                    ConnectorId = request.ConnectorId,
                    IdTag = request.Token,
                    ReservationId = request.ReservationId,
                    ExpiryDate = request.ExpiryDate.ToString(EVCBConfiguration.UTC_DATETIMEFORMAT)
                };

                var _innerResult = await _client.Post(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent() ),
                    $"/api/v1/ocpp{ocppProtocol}/reservation?ChargeBoxId={request.ChargeBoxId}",
                    new Dictionary<string, string>()
                        {
                            { "PartnerId",_CustomerId}

                        }, 
                    _innerRequest,
                    _customer.GetAPIKey(new Guid(_CustomerId)));


                _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                result = GetErrorDescription(_innerResult);
                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                if (_innerResult.Success)
                {
                    result.SerialNo = _innerResult.SerialNo;
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                else
                {

                    if (_innerResult.ErrorCode == (int)CPO_StatusCode.UnexpectedError)
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                    else
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = statusCode = StatusCodes.Status400BadRequest;
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("commands/cancel_reservation")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpDelete]
        async public Task<IActionResult> CancelReservation(string ChargeBoxId, int ReservationId)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }


                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();


                string urlformat = "{0}://{1}";
                string ocppProtocol = GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";

                var _innerResult = await _client.Delete(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent()), 
                    $"/api/v1/ocpp{ocppProtocol}/reservation?ChargeBoxId={ChargeBoxId}&ReservationId={ReservationId}",
                    new Dictionary<string, string>()
                    {
                        { "PartnerId",_CustomerId}

                    }, _customer.GetAPIKey(new Guid(_CustomerId)));


                _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                result = GetErrorDescription(_innerResult);
                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                if (_innerResult.Success)
                {
                    result.SerialNo = _innerResult.SerialNo;
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                else
                {

                    if (_innerResult.ErrorCode == (int)CPO_StatusCode.UnexpectedError)
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                    else
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("commands/set_locallist")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpPost]
        async public Task<IActionResult> SendLocalList(string ChargeBoxId, [FromBody] LocalListRequest request)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }


                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                string urlformat = "{0}://{1}";
                string ocppProtocol = GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";


                var _innerResult = await _client.Post(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent()), 
                    $"/api/v1/ocpp{ocppProtocol}/locallist?ChargeBoxId={ChargeBoxId}",
                    new Dictionary<string, string>()
                    {
                        { "PartnerId",_CustomerId}

                    }, 
                    request, 
                    _customer.GetAPIKey(new Guid(_CustomerId)));


                _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                result = GetErrorDescription(_innerResult);
                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                if (_innerResult.Success)
                {
                    result.SerialNo = _innerResult.SerialNo;
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                else
                {

                    if (_innerResult.ErrorCode == (int)CPO_StatusCode.UnexpectedError)
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                    else
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("commands/locallistversion")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        async public Task<IActionResult> GetLocalListVersion(string ChargeBoxId)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;
            var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }


                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                string urlformat = "{0}://{1}";
                string ocppProtocol = GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";

                var _innerResult = await _client.Get(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent()), 
                    $"/api/v1/ocpp{ocppProtocol}/locallistversion?ChargeBoxId={ChargeBoxId}",
                    new Dictionary<string, string>()
                    {
                        { "PartnerId",_CustomerId}

                    }, _customer.GetAPIKey(new Guid(_CustomerId)));


                _innerData = new { Result = string.IsNullOrEmpty(_innerResult.SerialNo) ? CommandResponseType.Rejected.ToString() : CommandResponseType.Accepted.ToString(), Timeout = 60 };
                result = GetErrorDescription(_innerResult);
                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                if (_innerResult.Success)
                {
                    result.SerialNo = _innerResult.SerialNo;
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;
                }
                else
                {

                    if (_innerResult.ErrorCode == (int)CPO_StatusCode.UnexpectedError)
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_INNERSERVICE_ERROR;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                    else
                    {
                        result.StatusCode = _innerResult.ErrorCode;
                        result.StatusMessage = _innerResult.Message;
                        //statusCode = HttpStatusCode.BadRequest;
                        statusCode = StatusCodes.Status400BadRequest;
                    }
                }

                //statusCode = HttpStatusCode.OK;
                statusCode = StatusCodes.Status200OK;
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("commands/results")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        async public Task<IActionResult> ExecutionofCmdSearch(string ChargeBoxId, CommandType? commandType, string SerialNo)
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;

            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }

                InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();

                int? orderNo = (int?)null;

                switch (commandType.Value)
                {
                    case CommandType.CancelReservation:
                        {
                            orderNo = 4;
                        }
                        break;
                    case CommandType.ClearChargingProfile:
                        {
                            orderNo = 6;
                        }
                        break;
                    case CommandType.GetAcitveChargingProfile:
                        {
                            orderNo = 7;
                        }
                        break;
                    case CommandType.GetLocalListVersion:
                        {
                            orderNo = 9;
                        }
                        break;
                    case CommandType.Start_Session:
                        {
                            orderNo = 10;
                        }
                        break;
                    case CommandType.Stop_Session:
                        {
                            orderNo = 11;
                        }
                        break;
                    case CommandType.Reserve_Now:
                        {
                            orderNo = 12;
                        }
                        break;
                    case CommandType.SetLocalList:
                        {
                            orderNo = 14;
                        }
                        break;
                    case CommandType.SetChargingProfile:
                        {
                            orderNo = 15;
                        }
                        break;
                    default:
                        {
                            orderNo = 18;
                        }
                        break;
                }

                string urlformat = "{0}://{1}";
                var ocppPortocol = GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16 ? "16" : "20";


                var _innerResult = await _client.Get(
                    string.Format(urlformat, Request.Scheme, Request.Host.ToUriComponent()), 
                    string.Format("/api/v1/ocpp{{0}}/command?ChargeBoxId={{1}}{{2}}&SerialNo={{3}}", ocppPortocol, ChargeBoxId, orderNo.HasValue ? "&OrderNo=" + orderNo.Value : "", SerialNo),
                    new Dictionary<string, string>()
                    {
                        { "PartnerId",_CustomerId}

                    }, _customer.GetAPIKey(new Guid(_CustomerId)));


                result = GetErrorDescription(_innerResult);

                if (_innerResult.Success)
                {
                    ComandExecution _execution = JsonConvert.DeserializeObject<ComandExecution>(_innerResult.Message);

                    CommandResultType? _cmdResult = (CommandResultType?)null;

                    switch (_execution.Code)
                    {
                        case 1:
                            {
                                _cmdResult = CommandResultType.Accepted;
                            }
                            break;
                        case 9:
                            {
                                _cmdResult = CommandResultType.Notsupported;
                            }
                            break;
                        case 10:
                            {
                                _cmdResult = CommandResultType.Unknown;
                            }
                            break;
                        case 26:
                            {
                                _cmdResult = CommandResultType.Occupied;
                            }
                            break;
                        case 31:
                            {
                                _cmdResult = CommandResultType.Rejected;
                            }
                            break;
                        case 32:
                            {
                                _cmdResult = CommandResultType.Failed;
                            }
                            break;
                        case 254:
                            {
                                _cmdResult = CommandResultType.EVSE_ERROR;
                            }
                            break;
                        default:
                            {
                                if (_execution.Detail == "Timeout") _cmdResult = CommandResultType.Timeout;
                                if (_execution.Detail == "Waited") _cmdResult = CommandResultType.Waited;

                            }
                            break;


                    }


                    if (!_cmdResult.HasValue)
                    {
                        result.StatusCode = (int)CPO_StatusCode.CANT_FOUND_DATA;
                        result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_RESULT;
                        //statusCode = HttpStatusCode.NotFound;
                        statusCode = StatusCodes.Status404NotFound;
                    }
                    else
                    {
                        var _innerData = new { Result = _cmdResult.Value.ToString(), Message = _execution.Detail };
                        result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                        result.SerialNo = _innerResult.SerialNo;
                        result.StatusCode = (int)CPO_StatusCode.Success;
                        result.StatusMessage = CPO_StatusMessage.Success;
                        //statusCode = HttpStatusCode.OK;
                        statusCode = StatusCodes.Status200OK;
                    }

                }


            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

            return StatusCode(statusCode, result);
        }

        [Route("activesession")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult ActiveSession(string ChargeBoxId, string SessionId = "", string IdTag = "")
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;

            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }

                // query meter value
                IChargePointService _service = null;
                if (GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16)
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint16Service>();
                }
                else
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint201Service>();
                }
                var transactionDatas = _service.GetActiveSessionInfo(ChargeBoxId, new List<Measurand>()
                {  Measurand.Voltage,
                   Measurand.Current_Import,
                   Measurand.SoC,
                   Measurand.Power_Active_Import,
                   Measurand.TotalEnergy,
                   Measurand.ChargingCost
                }, SessionId, IdTag);

                if (transactionDatas == null)
                {
                    result.StatusCode = (int)CPO_StatusCode.CANT_FOUND_DATA;
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_RESULT;
                    //statusCode = HttpStatusCode.NotFound;
                    statusCode = StatusCodes.Status404NotFound;
                }
                else
                {
                    List<ActiveSession> _innerData = new List<ActiveSession>();

                    foreach (var transactionData in transactionDatas)
                    {
                        string currencyText = string.IsNullOrEmpty(transactionData.Fee)?"":transactionData.Fee.Split('|')[1];

                        _innerData.Add(new ActiveSession()
                        {

                            ChargeBoxId = ChargeBoxId,
                            SessionId = transactionData.Id,
                            ElaspedTime = (int)DateTime.UtcNow.Subtract(transactionData.StartTime).TotalMinutes,
                            ConnectorId = transactionData.ConnectorId,
                            IdTag = transactionData.StartIdTag,
                            Power = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Power_Active_Import).Select(x => x.Value).FirstOrDefault(),
                            Power_Format = transactionData.MeterValues == null ? UnitOfMeasure.W.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Power_Active_Import).Select(x => x.Unit.ToString()).FirstOrDefault(),
                            Current = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Current_Import).Select(x => x.Value).FirstOrDefault(),
                            Current_Format = transactionData.MeterValues == null ? UnitOfMeasure.A.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Current_Import).Select(x => x.Unit.ToString()).FirstOrDefault(),
                            Energy = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.TotalEnergy).Select(x => x.Value).FirstOrDefault(),
                            Energy_Format = transactionData.MeterValues == null ? UnitOfMeasure.Wh.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.TotalEnergy).Select(x => x.Unit.ToString()).FirstOrDefault(),
                            Voltage = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Voltage).Select(x => x.Value).FirstOrDefault(),
                            Voltage_Format = transactionData.MeterValues == null ? UnitOfMeasure.V.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Voltage).Select(x => x.Unit.ToString()).FirstOrDefault(),
                            SOC = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Unit.ToString()).FirstOrDefault() == null ? null : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Value).FirstOrDefault(),
                            SOC_Format = transactionData.MeterValues == null ? UnitOfMeasure.Percent.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Unit.ToString()).FirstOrDefault(),
                            CurrentCost = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.ChargingCost).Select(x => x.Value).FirstOrDefault(),
                            Currency = currencyText
                        });
                        decimal energy = decimal.Parse(_innerData[_innerData.Count - 1].Energy);
                        energy = _innerData[_innerData.Count - 1].Energy_Format == UnitOfMeasure.Wh.ToString() ? Decimal.Divide(energy, 1000) : energy;



                    }
                    result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                    result.StatusCode = (int)CPO_StatusCode.Success;
                    result.StatusMessage = CPO_StatusMessage.Success;
                    //statusCode = HttpStatusCode.OK;
                    statusCode = StatusCodes.Status200OK;

                }

                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

        }

        [Route("completedsession")]
        [Produces(typeof(CPOOuterResponse))]
        [HttpGet]
        public IActionResult CompletedSession(string ChargeBoxId, int SessionId = -1, string IdTag = "", string StartTime = "", string StopTime = "")
        {
            var result = new CPOOuterResponse();
            //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
            int statusCode = StatusCodes.Status500InternalServerError;

            try
            {
                string _CustomerId = string.Empty;

                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
                {
                    // 沒槍~ 沒得充...                   
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
                    result.StatusCode = (int)CPO_StatusCode.CHARGEBOXID_ISNT_EXIST_OR_OFFLINE;
                    //statusCode = HttpStatusCode.BadRequest;
                    statusCode = StatusCodes.Status400BadRequest;
                    return StatusCode(statusCode, result);
                }

                DateTime startDt = string.IsNullOrEmpty(StartTime) ? new DateTime(1991, 1, 1) : DateTime.Parse(StartTime);
                DateTime stopDt = string.IsNullOrEmpty(StopTime) ? new DateTime(1991, 1, 1) : DateTime.Parse(StopTime);
                // query meter value
                IChargePointService _service = null;
                if (GetChargePointOCPPProtocol(ChargeBoxId) == OCPPProtocolType.OCPP16)
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint16Service>();
                }
                else
                {
                    _service = serviceProvider.GetRequiredService<ChargePoint201Service>();
                }
                var _innerData = _service.GetSessionDetail(ChargeBoxId, SessionId, IdTag, startDt, stopDt);

                if (_innerData == null)
                {
                    result.StatusCode = (int)CPO_StatusCode.CANT_FOUND_DATA;
                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_SESSIONDETAIL;
                    //statusCode = HttpStatusCode.NotFound;
                    statusCode = StatusCodes.Status404NotFound;
                    return StatusCode(statusCode, result);
                }

                result.Data = JsonConvert.SerializeObject(_innerData, EVCBConfiguration.JSONSERIALIZER_FORMAT);
                result.StatusCode = (int)CPO_StatusCode.Success;
                result.StatusMessage = CPO_StatusMessage.Success;
                //statusCode = HttpStatusCode.OK;
                statusCode = StatusCodes.Status200OK;
                return StatusCode(statusCode, result);
            }
            catch (Exception ex)
            {
                result.ErrorDetail = ex.ToString();
                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_UNEXPECTEDERROR;
                result.StatusCode = (int)CPO_StatusCode.UnexpectedError;
                return StatusCode(statusCode, result);
            }

        }



        #region private method

        private bool ContainsChargePoint(string chargeBoxId, out string customerId)
        {
            customerId = string.Empty;

            if (!Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId)) return false;

            customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();

            ChargePoint201Service _service201 = serviceProvider.GetRequiredService<ChargePoint201Service>();
            ChargePoint16Service _service16 = serviceProvider.GetRequiredService<ChargePoint16Service>();


            return _service16.ContainsChargePoint(chargeBoxId, customerId) ? true : _service201.ContainsChargePoint(chargeBoxId, customerId) ? true : false;

        }


        private OCPPProtocolType GetChargePointOCPPProtocol(string chargeBoxId)
        {
            ChargePoint201Service _service201 = serviceProvider.GetRequiredService<ChargePoint201Service>();
            ChargePoint16Service _service16 = serviceProvider.GetRequiredService<ChargePoint16Service>();

            return _service201.GetMachineUpdatedOn(chargeBoxId) > _service16.GetMachineUpdatedOn(chargeBoxId)
                ? OCPPProtocolType.OCPP201 : OCPPProtocolType.OCPP16;

        }

        private CPOOuterResponse GetErrorDescription(InternalHttpResult innerResponse)
        {
            CPOOuterResponse result = new CPOOuterResponse();

            result.ErrorDetail = innerResponse.Exception == null ? null : innerResponse.Exception.ToString();

            if (innerResponse.Status != HttpStatusCode.Accepted)
            {
                switch (innerResponse.ErrorCode)
                {
                    #region Authorization
                    case 2000:
                        {
                            result.StatusCode = innerResponse.ErrorCode;
                            result.StatusMessage = string.Format("{0}-{1}", "InnerService", "Authorize Unexpected Error");
                            result.ErrorDetail = result.StatusMessage;
                        }
                        break;
                    case 2001:
                    case 2002:
                    case 2003:
                        {
                            result.StatusCode = innerResponse.ErrorCode;
                            result.StatusMessage = string.Format("{0}-{1}", "InnerService", innerResponse.Message);
                        }
                        break;

                    #endregion
                    case 2100:
                    case 2101:
                    case 2102:
                    case 2103:
                    case 2104:
                    case 2105:
                    case 2106:
                        {
                            result.StatusCode = innerResponse.ErrorCode;
                            result.StatusMessage = innerResponse.Message;
                        }
                        break;
                    case 2999:
                        {
                            result.StatusCode = innerResponse.ErrorCode;
                            result.StatusMessage = string.Format("{0}-{1}", "InnerService", "Unexpected Error");
                            result.ErrorDetail = result.StatusMessage;
                        }
                        break;
                    default:
                        {
                            result.StatusCode = 2998;
                            result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_ERRORCODE;
                        }
                        break;
                }
            }

            return result;


        }


        #endregion
    }
}