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

namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync;

internal class DeactivateTemplatesStage : IGroupedSyncWriteStage
{
    private readonly ITemplateRepository _templateRepository;
    private readonly ITemplateDeactivator _deactivator;
    private readonly ILogger<DeactivateTemplatesStage> _logger;

    public string StageName => "Деактивация шаблонов";

    public DeactivateTemplatesStage(
        ITemplateRepository templateRepository,
        ITemplateDeactivator deactivator,
        ILogger<DeactivateTemplatesStage> logger)
    {
        _templateRepository = templateRepository;
        _deactivator = deactivator;
        _logger = logger;
    }

    public async Task<GroupedSyncContext> ExecuteAsync(GroupedSyncContext context, CancellationToken ct = default)
    {
        var allJobIds = context.JobsInGroup.Select(j => j.Id).ToHashSet();

        var existingTemplates = await _templateRepository.Get()
            .AsNoTracking()
            .Include(t => t.Unit)
            .Include(t => t.Job)
            .Include(t => t.UnitsInTemplate)
            .Where(t => allJobIds.Contains(t.JobId)
                        && t.StatusTypeId == TemplateStatusTypeEnum.Used
                        && t.Job!.GroupId == context.JobGroupId)
            .ToListAsync(ct);

        int deactivated = 0;
        foreach (var template in existingTemplates)
        {
            var key = (template.JobId, template.UnitId, template.Index ?? -1);
            if (!context.ExpectedTemplateKeys.Contains(key))
            {
                var unitLogName = context.UnitNames.TryGetValue(template.UnitId, out var unitName)
                    ? $"'{unitName}' ({template.UnitId})"
                    : template.Unit != null
                        ? $"'{template.Unit.Name}' ({template.UnitId})"
                        : $"({template.UnitId})";

                _logger.LogInformation(
                    "JobGroup '{JobGroupName}' ({JobGroupId}): деактивация шаблона '{TemplateName}' ({TemplateId}), Job '{JobName}' ({JobId}), Unit {Unit}",
                    context.JobGroupName, context.JobGroupId,
                    template.Name, template.Id,
                    template.Job?.Name ?? string.Empty, template.JobId,
                    unitLogName);

                await _deactivator.DeactivateTemplateAsync(template, context.Initiator);
                deactivated++;
            }
        }

        _logger.LogDebug("JobGroup '{JobGroupName}' ({JobGroupId}): деактивировано {Count} шаблонов из {Total}",
            context.JobGroupName, context.JobGroupId, deactivated, existingTemplates.Count);

        return context;
    }
}