// ValidatorService.cs
using Microsoft.EntityFrameworkCore;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.Job;
using PARR.DAL.Services.Interfaces.Unit;

namespace PARR.TemplateGeneratorWorker.Services
{
    internal class ValidatorService : IValidatorService
    {
        private readonly ILogger<ValidatorService> logger;
        private readonly IJobService jobService;
        private readonly IUnitService unitService;
        private readonly ITemplateService templateService;

        public ValidatorService(
            ILogger<ValidatorService> logger,
            IJobService jobService,
            IUnitService unitService,
            ITemplateService templateService
            )
        {
            this.logger = logger;
            this.jobService = jobService;
            this.unitService = unitService;
            this.templateService = templateService;
        }


        public async Task<bool> IsValidAsync(Guid jobId, Guid unitId, int? index, List<Guid>? unitsInTemplate = null)
        {
            // Проверяем JobId
            var job = await jobService
                                .Get().AsNoTracking()
                                .FirstOrDefaultAsync(t => t.Id == jobId);

            if (job == null)
            {
                logger.LogError($"Не найдена регалментная работа {nameof(jobId)}: {jobId}");
                return false;
            }

            // Проверяем UnitId (UnitId - это ID регионального юнита)
            var unit = await unitService
                .Get().AsNoTracking()
                .FirstOrDefaultAsync(t => t.Id == unitId);

            if (unit == null)
            {
                logger.LogError($"Не найден элемент конфигурации {nameof(unitId)}: {unitId}");
                return false;
            }

            // Проверяем уникальность (JobId, UnitId, Index)
            var existingTemplate = await templateService
                .Get().AsNoTracking()
                .FirstOrDefaultAsync(t => t.JobId == jobId && t.UnitId == unitId && t.Index == index);

            if (existingTemplate != null)
            {
                logger.LogError("Шаблон с JobId={JobId}, UnitId={UnitId}, Index={Index} уже существует.", jobId, unitId, index);
                return false;
            }

            // Проверяем, что все UnitId в UnitsInTemplate существуют (если список не null и не пуст)
            if (unitsInTemplate != null && unitsInTemplate.Any())
            {
                var unitIdsToCheck = unitsInTemplate.ToHashSet();
                var existingUnitIdsCount = await unitService.Get()
                    .AsNoTracking()
                    .Where(u => unitIdsToCheck.Contains(u.Id))
                    .Select(u => u.Id)
                    .CountAsync();

                if (existingUnitIdsCount != unitIdsToCheck.Count)
                {
                    logger.LogError("Не все UnitId из UnitsInTemplate существуют в базе данных. Ожидается: {ExpectedCount}, Найдено: {FoundCount}", unitIdsToCheck.Count, existingUnitIdsCount);
                    return false;
                }
            }

            return true;
        }
    }
}