using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using SumaTube.Domain.Entities.Videos;
using SumaTube.Infra.Contracts.Repositories.Videos;

namespace SumaTube.Infra.MongoDB.Repositories.Videos
{
    public class VideoSummaryRepository : IVideoSummaryRepository
    {
        private readonly IMongoCollection<VideoSummary> _collection;
        private readonly ILogger<VideoSummaryRepository> _logger;

        public VideoSummaryRepository(IMongoDatabase database, ILogger<VideoSummaryRepository> logger)
        {
            _collection = database.GetCollection<VideoSummary>("VideoSummaries");
            _logger = logger;
        }

        public async Task<VideoSummary> GetByIdAsync(string id)
        {
            _logger.LogInformation("Obtendo resumo por ID: {Id}", id);
            return await _collection.Find(x => x.Id == id).FirstOrDefaultAsync();
        }

        public async Task<List<VideoSummary>> GetByUserIdAsync(string userId)
        {
            _logger.LogInformation("Obtendo resumos do usuário: {UserId}", userId);
            return await _collection.Find(x => x.UserId == userId)
                                    .SortByDescending(x => x.RequestDate)
                                    .ToListAsync();
        }

        public async Task AddAsync(VideoSummary videoSummary)
        {
            _logger.LogInformation("Adicionando novo resumo. ID: {Id}, VideoId: {VideoId}",
                videoSummary.Id, videoSummary.VideoId);
            await _collection.InsertOneAsync(videoSummary);
        }

        public async Task UpdateAsync(VideoSummary videoSummary)
        {
            _logger.LogInformation("Atualizando resumo. ID: {Id}, Status: {Status}",
                videoSummary.Id, videoSummary.Status);
            await _collection.ReplaceOneAsync(x => x.Id == videoSummary.Id, videoSummary);
        }

        public async Task<bool> ExistsAsync(string videoId, string userId, string language)
        {
            _logger.LogInformation("Verificando existência de resumo. VideoId: {VideoId}, UserId: {UserId}, Language: {Language}",
                videoId, userId, language);

            var count = await _collection.CountDocumentsAsync(x =>
                x.VideoId == videoId &&
                x.UserId == userId &&
                x.Language == language &&
                (x.Status == "REALIZADO" || x.Status == "PROCESSANDO"));

            return count > 0;
        }

        public async Task<VideoSummary> GetByVideoIdAndUserIdAndLanguageAsync(string videoId, string userId, string language)
        {
            _logger.LogInformation("Obtendo resumo por VideoId: {VideoId}, UserId: {UserId}, Language: {Language}",
                videoId, userId, language);

            return await _collection.Find(x =>
                x.VideoId == videoId &&
                x.UserId == userId &&
                x.Language == language)
                .FirstOrDefaultAsync();
        }
    }
}
