using Dapper;
using EVCB_OCPP.WEBAPI.Models.WebAPI;
using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using Microsoft.Data.SqlClient;
using System.Linq;
using EVCB_OCPP.WEBAPI.Helpers;
using EVCB_OCPP.Domain;
using System.Threading.Tasks;

namespace EVCB_OCPP.WEBAPI.Services.Integration
{
    
    /// <summary>
    /// 抓充電站資訊 從Web撈資料
    /// 因此沒有分 ocpp16....  機器
    /// </summary>
    public class ChargingStationService
    {
        private readonly IServiceProvider serviceProvider;
        private readonly SqlConnectionFactory<WebDBConetext> webDbConnectionFactory;
        private readonly SqlConnectionFactory<MainDBContext> mainDbConnectionFactory;

        //private readonly string webConnectionString;
        //private readonly  string main16ConnectionString;

        public ChargingStationService(IServiceProvider serviceProvider,
            SqlConnectionFactory<WebDBConetext> webDbConnectionFactory,
            SqlConnectionFactory<MainDBContext> mainDbConnectionFactory)
        {
            this.serviceProvider = serviceProvider;
            this.webDbConnectionFactory = webDbConnectionFactory;
            this.mainDbConnectionFactory = mainDbConnectionFactory;
            //webConnectionString = configuration.GetConnectionString("WebDBContext");
            //main16ConnectionString = configuration.GetConnectionString("MainDBContext");
        }

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

            var parameters = new DynamicParameters();
            parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input, 36);
            using (SqlConnection conn = webDbConnectionFactory.Create())
            {
                string strSql = "Select Id, Name ,Latitude,Longitude 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, 36);
            parameters.Add("@Id", stationId, DbType.Int32, ParameterDirection.Input);
            using (SqlConnection conn = webDbConnectionFactory.Create())
            {
                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 = 10)
        {
            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 = webDbConnectionFactory.Create())
            {
                string strSql = "Select MachineId from [dbo].[StationMachine] where StationId=@StationId; ";
                machineIds = conn.Query<String>(strSql, parameters).ToList();
            }
          
            while (startIndex < limit && startIndex < machineIds.Count)
            {
                var machine_by201 = serviceProvider.GetRequiredService<ChargePoint201Service>().GetBasicInfobyId(machineIds[startIndex]);
                var machine_by16 = serviceProvider.GetRequiredService<ChargePoint16Service>().GetBasicInfobyId(machineIds[startIndex]);
                var machine201UpdateOn = machine_by201==null? EVCBConfiguration.DefaultTime:machine_by201.LastUpdated;
                var machine16UpdateOn = machine_by16 == null ? EVCBConfiguration.DefaultTime : machine_by16.LastUpdated;
                int connectiontype = machine201UpdateOn > machine16UpdateOn ? 2 : 1;
                var machineUpdateOn = connectiontype == 2 ? machine201UpdateOn : machine16UpdateOn;
                var machine = connectiontype == 2 ? machine_by201 : machine_by16;
                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;
                }

           
                if (machine != null)
                {
                    machine.LastUpdated = machineUpdateOn;
                    machine.StationId = stationId;
                    _chargePoints.Add(machine);

                }
                else
                {
                    limit++;
                }

                startIndex++;

            }
            return _chargePoints;
        }

        public Station GetInfobyChargeBoxId(string chargeBoxId)
        {
            return GetInfobyChargeBoxIdAsync(chargeBoxId).Result;
        }

        public async Task<Station> GetInfobyChargeBoxIdAsync(string chargeBoxId)
        {
            Station result = null;
            var parameters = new DynamicParameters();
            parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
           
            string machineId = string.Empty;
            using (SqlConnection conn = mainDbConnectionFactory.Create())
            {
                string strSql = """
                    SELECT Machine.Id 
                    FROM [dbo].[Machine]
                    WHERE ChargeBoxId = @ChargeBoxId;
                    """;
                machineId = await conn.QueryFirstOrDefaultAsync<string>(strSql, parameters);
            }
            parameters.Add("@MachineId", machineId, DbType.String, ParameterDirection.Input, 36);
            using (SqlConnection conn = webDbConnectionFactory.Create())
            {
                string strSql = """
                    SELECT * 
                    FROM [dbo].[Station] station
                    WHERE Id IN ( 
                        SELECT StationId
                        FROM[dbo].[Machine],[dbo].[StationMachine]
                        WHERE StationMachine.MachineId= @MachineId
                        );
                    """;
                result = await conn.QueryFirstOrDefaultAsync<Station>(strSql, parameters);

            }

            return result;
        }


    }
}