using Dapper;
using EVCB_OCPP.WEBAPI.Models.WebAPI;
using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using Microsoft.Data.SqlClient;

namespace EVCB_OCPP.WEBAPI.Services
{

    public interface IChargingStationService
    {
        List<Station> GetStationsbyCustomerId(string customerId);

        List<EVSE> GetEVSEsbyStationId(int stationId, DateTime? dateFrom, DateTime? dateTo, int offset, int limit);

    }
    public class ChargingStationService : IChargingStationService
    {
        string mainConnectionString;
        string webConnectionString;
        private readonly IServiceProvider serviceProvider;

        public ChargingStationService(IConfiguration configuration, IServiceProvider serviceProvider)
        {
            mainConnectionString = configuration.GetConnectionString("MainDBContext");
            webConnectionString = configuration.GetConnectionString("WebDBContext");
            this.serviceProvider = serviceProvider;
        }

        public List<Station> GetStationsbyCustomerId(string customerId)
        {
            List<Station> _stations = new List<Station>();

            var parameters = new DynamicParameters();
            parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input);
            using (SqlConnection conn = new SqlConnection(webConnectionString))
            {
                string strSql = "Select Id, Name ,Latitude,Longitude,Address from [dbo].[Station] where CustomerId=@CustomerId; ";
                _stations = conn.Query<Station>(strSql, parameters).ToList();

            }

            if (_stations != null)
            {
                foreach (var station in _stations)
                {
                    station.Coordinates = new GetLocation() { Latitude = station.Latitude, Longitude = station.Longitude };
                    station.EVSEs = GetEVSEsbyStationId(station.Id, null, null, -1, 100000);

                }
            }
            return _stations;
        }

        public bool ContainsStation(string customerId, int stationId)
        {
            bool isContains = false;

            var parameters = new DynamicParameters();
            parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input);
            parameters.Add("@Id", stationId, DbType.Int32, ParameterDirection.Input);
            using (SqlConnection conn = new SqlConnection(webConnectionString))
            {
                string strSql = "Select count(*) from [dbo].[Station] where CustomerId=@CustomerId and Id=@Id; ";
                isContains = conn.ExecuteScalar<Int32>(strSql, parameters) > 0 ? true : false;
            }

            return isContains;
        }


        public List<EVSE> GetEVSEsbyStationId(int stationId, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
        {
            List<EVSE> _chargePoints = new List<EVSE>();
            var parameters = new DynamicParameters();
            parameters.Add("@StationId", stationId, DbType.Int16, ParameterDirection.Input);
            int counter = 0;
            int startIndex = offset == -1 ? 0 : offset;
            limit = limit + startIndex;
            List<string> machineIds = new List<string>();
            using (SqlConnection conn = new SqlConnection(webConnectionString))
            {
                string strSql = "Select MachineId from [dbo].[StationMachine] where StationId=@StationId; ";
                machineIds = conn.Query<String>(strSql, parameters).ToList();
            }
            ChargePointService _CPService = serviceProvider.GetRequiredService<ChargePointService>();// new ChargePointService();
            while (startIndex < limit && startIndex < machineIds.Count)
            {
                var _machineUpdateOn = _CPService.GetLastUpdatedTimebyMachineId(machineIds[startIndex]);


                if (dateFrom.HasValue && _machineUpdateOn < dateFrom.Value.ToUniversalTime())
                {
                    limit++;
                    startIndex++;
                    continue;
                }

                if (dateFrom.HasValue && dateTo.HasValue && (_machineUpdateOn < dateFrom.Value.ToUniversalTime() || _machineUpdateOn > dateTo.Value.ToUniversalTime()))
                {
                    limit++;
                    startIndex++;
                    continue;
                }

                var _machine = _CPService.GetBasicInfobyId(machineIds[startIndex]);
                if (_machine != null)
                {
                    _machine.LastUpdated = _machineUpdateOn;
                    _machine.StationId = stationId;
                    _chargePoints.Add(_machine);

                }
                else
                {
                    limit++;
                }

                startIndex++;

            }
            return _chargePoints;
        }




    }
}