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

namespace PARR.TemplateMatcher.Services.Implementations.SimpleSync;

internal class AnalyzeChangesStage : ISimpleSyncStage
{
    private readonly ITemplateRepository _templateRepository;
    private readonly ITemplateNameNormalizer _nameNormalizer;
    private readonly ILogger<AnalyzeChangesStage> _logger;

    public string StageName => "Анализ изменений";

    public AnalyzeChangesStage(
        ITemplateRepository templateRepository,
        ITemplateNameNormalizer nameNormalizer,
        ILogger<AnalyzeChangesStage> logger)
    {
        _templateRepository = templateRepository;
        _nameNormalizer = nameNormalizer;
        _logger = logger;
    }

    public async Task<SimpleSyncContext> ExecuteAsync(SimpleSyncContext context, CancellationToken ct = default)
    {
        var existing = await _templateRepository.Get()
            .Include(t => t.UnitsInTemplate)
            .Include(t => t.Job).ThenInclude(t => t!.Group).ThenInclude(t => t!.GroupType)
            .Include(t => t.Job).ThenInclude(t => t!.Tnk)
            .Include(t => t.Unit)
            .Where(t => t.JobId == context.JobId)
            .ToListAsync(ct);

        var used = existing.Where(t => t.StatusTypeId == TemplateStatusTypeEnum.Used).ToList();
        var existingUnitIds = used.Select(t => t.UnitId).ToHashSet();

        context.ExistingUsedTemplates = used;
        context.NewUnitIds = context.FilteredUnitIds.Except(existingUnitIds).ToList();
        context.UnusedTemplates = used.Where(t => !context.FilteredUnitIds.Contains(t.UnitId)).ToList();

        foreach (var template in used)
        {
            if (!context.FilteredUnitIds.Contains(template.UnitId)) continue;

            var expectedName = await _nameNormalizer.GetNormalizedTemplateNameAsync(template);
            if (!string.Equals(template.Name, expectedName, StringComparison.OrdinalIgnoreCase))
                context.TemplatesToRename.Add((template, expectedName));
        }

        _logger.LogDebug(
            "Job '{JobName}' ({JobId}): существующих шаблонов={Existing}, создать={Create}, деактивировать={Deactivate}, переименовать={Rename}",
            context.JobName, context.JobId,
            used.Count, context.NewUnitIds.Count, context.UnusedTemplates.Count, context.TemplatesToRename.Count);

        return context;
    }
}