using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.Core.Repositories.Interfaces.JobGroupRepositories;
using PARR.TemplateMatcher.Services.GroupedSync;

namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync;

internal class LoadJobGroupStage : IGroupedSyncStage
{
    private readonly IJobGroupRepository _jobGroupRepository;
    private readonly ILogger<LoadJobGroupStage> _logger;

    public string StageName => "Загрузка JobGroup";

    public LoadJobGroupStage(IJobGroupRepository jobGroupRepository, ILogger<LoadJobGroupStage> logger)
    {
        _jobGroupRepository = jobGroupRepository;
        _logger = logger;
    }

    public async Task<GroupedSyncContext> ExecuteAsync(GroupedSyncContext context, CancellationToken ct = default)
    {
        var jobGroup = await _jobGroupRepository.Get()
            .AsNoTracking()
            .AsSingleQuery()
            .Include(jg => jg.GroupType)
            .Include(jg => jg.AutoControl)
            .Include(jg => jg.Jobs).ThenInclude(j => j.AutoControl)
            .Include(jg => jg.Jobs).ThenInclude(j => j.UnitFilters)
                .ThenInclude(uf => uf.RelationshipFilters).ThenInclude(rf => rf.UnitField)
            .Include(jg => jg.Jobs).ThenInclude(jg => jg.Tnk)
            .FirstOrDefaultAsync(jg => jg.Id == context.JobGroupId, ct);

        if (jobGroup == null || jobGroup.Jobs == null || !jobGroup.Jobs.Any())
            throw new GroupedSyncEarlyExitException("JobGroup не найден или пуст");

        var jobsInGroup = jobGroup.Jobs.ToList();
        var maxJob = jobsInGroup
            .Where(j => j.MaxValueRelationships.HasValue)
            .OrderByDescending(j => j.MaxValueRelationships)
            .FirstOrDefault();

        if (maxJob == null)
            throw new GroupedSyncEarlyExitException("Не найден Job с MaxValueRelationships");

        context.JobGroup = jobGroup;
        context.JobGroupName = jobGroup.GroupName;
        context.JobsInGroup = jobsInGroup;
        context.MaxJob = maxJob;

        _logger.LogDebug("JobGroup '{JobGroupName}' ({JobGroupId}): загружено {JobCount} Job'ов, эталонный Job '{MaxJobName}' ({MaxJobId})",
            jobGroup.GroupName, jobGroup.Id, jobsInGroup.Count, maxJob.Name, maxJob.Id);

        return context;
    }
}