using EVCB_OCPP.Domain;
using EVCB_OCPP.Domain.Models.Database;
using EVCB_OCPP.Packet.Messages.SubTypes;
using EVCB_OCPP.WSServer.Dto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace EVCB_OCPP.WSServer.Service;


public interface IBusinessService
{
    Task<IdTokenInfo> Authorize(string chargeBoxId, string idTag, int? connectorId = null);

    Task NotifyFaultStatus(ErrorDetails details);

    Task NotifyConnectorUnplugged(string chargeBoxId,string data);

}

public static class BusinessServiceFactoryRegistration
{
    public static void AddBusinessServiceFactory(this IServiceCollection services)
    {
        services.AddSingleton<HttpClientService>();
        services.AddSingleton<OuterHttpClient>();

        services.AddTransient<OuterBusinessService>();
        services.AddTransient<LocalBusinessService>();
        services.AddSingleton<IBusinessServiceFactory, BusinessServiceFactory>();
    }
}

public class BusinessServiceFactory : IBusinessServiceFactory
{

    public BusinessServiceFactory(
        IServiceProvider serviceProvider,
        IMainDbService mainDbService
        //IDbContextFactory<MainDBContext> mainDBContextFactory
        )
    {
        this.serviceProvider = serviceProvider;
        this.mainDbService = mainDbService;
        //this.mainDBContextFactory = mainDBContextFactory;
    }

    private readonly IServiceProvider serviceProvider;
    private readonly IMainDbService mainDbService;

    //private readonly IDbContextFactory<MainDBContext> mainDBContextFactory;

    public async Task<IBusinessService> CreateBusinessService(string customerId)
    {
        bool isCallOut = false;
        //using (var db = this.mainDBContextFactory.CreateDbContextAsync())
        //{
        //    isCallOut = await db.Customer.Where(x => x.Id == new Guid(customerId)).Select(x => x.CallPartnerApiOnSchedule).FirstOrDefaultAsync();
        //}
        CustomerSignMaterial _customer = null;
        //using (var db = this.mainDBContextFactory.CreateDbContextAsync())
        //{
        //    _customer = await db.Customer.Where(x => x.Id == new Guid(customerId)).Select(x => new CustomerSignMaterial() { Id = x.Id.ToString(), APIUrl = x.ApiUrl, SaltKey = x.ApiKey, CallsThirdParty = x.CallPartnerApiOnSchedule }).FirstOrDefaultAsync();
        //}
        var _customerDb = await mainDbService.GetCustomer(customerId);
        if (_customerDb is not null)
        {
            _customer = new CustomerSignMaterial() { 
                Id = _customerDb.Id.ToString(),
                APIUrl = _customerDb.ApiUrl,
                SaltKey = _customerDb.ApiKey,
                CallsThirdParty = _customerDb.CallPartnerApiOnSchedule
            };
        }
        isCallOut = _customer != null && _customer.CallsThirdParty;
        //return isCallOut ? new OuterBusinessService(customerId) : new LocalBusinessService(customerId);
        if (isCallOut)
        {
            OuterBusinessService outerBusinessService = serviceProvider.GetService<OuterBusinessService>();
            //outerBusinessService.CustomerId = customerId;
            outerBusinessService.CustomerSignMaterial = _customer;
            return outerBusinessService;
        }
        LocalBusinessService toReturn = serviceProvider.GetService<LocalBusinessService>();
        toReturn.CustomerId = customerId;
        return toReturn;

        //return isCallOut ? new OuterBusinessService(customerId) : 
    }

}