using e_suite.API.Common.models;
using e_suite.Database.Audit;
using e_suite.Service.SigmaImporter.Repository;
using e_suite.Utilities.Pagination;
using e_suite.Service.SigmaImporter.Extensions;

namespace e_suite.Service.SigmaImporter.PrintSpecifications;

public partial class PrintSpecificationImporter : IPrintSpecificationImporter
{
    private Dictionary<string, string> _hostnameDictionary = new Dictionary<string, string>();

    private async Task<List<GetDomain>> ImportDomains(AuditUserDetails auditUserDetails)
    { 
        var eSuiteDomains = await LoadExistingDomains();
        var sigmaDomains = await LoadSigmaDomains();

        await AddMissingDomainsToESuite(eSuiteDomains, sigmaDomains, auditUserDetails);

        return eSuiteDomains;
    }

    private async Task AddMissingDomainsToESuite(List<GetDomain> eSuiteDomains, List<SigmaDomain> sigmaDomains, AuditUserDetails auditUserDetails)
    {
        foreach (var sigmaDomain in sigmaDomains)
        {
            var esuiteDomain = FindESuiteDomainByHostname(eSuiteDomains, sigmaDomain.Hostname);
            if (esuiteDomain != null)
                continue;
            
            //Need to add the new domain to esuite here.
            var createDomain = new CreateDomain
            {
                Name = sigmaDomain.Name,
                SunriseHostName = sigmaDomain.Hostname,
                SigmaId = sigmaDomain.Id,
                Guid = Guid.NewGuid()
            };

            await _domainManager.CreateDomainAsync(auditUserDetails, createDomain, CancellationToken.None);
            var newDomain = await _domainManager.GetDomainAsync(createDomain.Guid.Value.ToGeneralIdRef(), CancellationToken.None);

            eSuiteDomains.Add(newDomain);
        }
    }

    private GetDomain? FindESuiteDomainByHostname(List<GetDomain> eSuiteDomains, string sigmaDomainHostname)
    {
        return eSuiteDomains.FirstOrDefault(eSuiteDomain => eSuiteDomain.SunriseHostName.Equals(sigmaDomainHostname));
    }

    private async Task<List<SigmaDomain>> LoadSigmaDomains()
    {
        await PrepareHostnameDictionary();

        var sigmaDomains = (await _sigmaRepository.GetDomains()).ToList();
        foreach (var sigmaDomain in sigmaDomains)
        {
            if (_hostnameDictionary.TryGetValue(sigmaDomain.Tla, out var hostname))
                sigmaDomain.Hostname = hostname;
        }

        return sigmaDomains;
    }

    private async Task<List<GetDomain>> LoadExistingDomains()
    {
        var domainList = (await _domainManager.GetDomainsAsync(new Paging() { Page = 0 }, CancellationToken.None)).Data.ToList();

        return domainList;
    }

    private async Task PrepareHostnameDictionary()
    {
        _hostnameDictionary.Clear();
        var tlaHostNames = await _airlockRepository.GetActivePrintSpecifications();
        foreach (var tlaHostname in tlaHostNames)
        {
            _hostnameDictionary.Add(tlaHostname.Tla, tlaHostname.Hostname);
        }
    }
}
