MVCPostall/Postall.Infra.MongoDB/Repositories/ChannelRepository.cs
2025-03-04 19:06:01 -03:00

245 lines
9.0 KiB
C#

using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using Postall.Domain;
using Postall.Domain.Dtos;
using Postall.Domain.Entities;
using Postall.Infra.MongoDB.Settings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Postall.Infra.MongoDB.Repositories
{
public class ChannelRepository : IChannelRepository
{
private readonly IMongoCollection<ChannelData> _channelsCollection;
public ChannelRepository(IOptions<MongoDbSettings> mongoDbSettings)
{
var client = new MongoClient(mongoDbSettings.Value.ConnectionString);
var database = client.GetDatabase(mongoDbSettings.Value.DatabaseName);
_channelsCollection = database.GetCollection<ChannelData>(mongoDbSettings.Value.ChannelsCollectionName);
var indexKeysDefinition = Builders<ChannelData>.IndexKeys.Ascending(c => c.YoutubeId);
_channelsCollection.Indexes.CreateOne(new CreateIndexModel<ChannelData>(indexKeysDefinition, new CreateIndexOptions { Unique = true }));
var textIndexDefinition = Builders<ChannelData>.IndexKeys
.Text(c => c.Title)
.Text(c => c.Description);
_channelsCollection.Indexes.CreateOne(new CreateIndexModel<ChannelData>(textIndexDefinition));
}
/// <summary>
/// Obtém todos os canais
/// </summary>
public async Task<IEnumerable<ChannelData>> GetAllAsync()
{
return await _channelsCollection.Find(c => true).ToListAsync();
}
/// <summary>
/// Obtém um canal pelo ID do MongoDB
/// </summary>
public async Task<ChannelData> GetByIdAsync(string id)
{
if (!ObjectId.TryParse(id, out _))
return null;
return await _channelsCollection.Find(c => c.Id == id).FirstOrDefaultAsync();
}
public async Task<IList<ChannelData>> GetByUserIdAsync(string userId)
{
return await _channelsCollection.Find(c => c.UserId == userId).ToListAsync();
}
/// <summary>
/// Obtém os canais pelo ID do usuario e o channelId
/// </summary>
public async Task<ChannelData> GetByUserIdAndChannelIdAsync(string userId, string channelId)
{
return await _channelsCollection.Find(c => c.UserId == userId && c.ChannelId == channelId).FirstOrDefaultAsync();
}
/// <summary>
/// Obtém um canal pelo ID do YouTube
/// </summary>
public async Task<ChannelData> GetByYoutubeIdAsync(string youtubeId)
{
return await _channelsCollection.Find(c => c.YoutubeId == youtubeId).FirstOrDefaultAsync();
}
/// <summary>
/// Adiciona um novo canal
/// </summary>
public async Task<ChannelData> AddAsync(ChannelData ChannelData)
{
// Verifica se o canal já existe pelo ID do YouTube
var existingChannel = await GetByYoutubeIdAsync(ChannelData.YoutubeId);
if (existingChannel != null)
return null;
// Gera novo ID para o MongoDB se não for fornecido
if (string.IsNullOrEmpty(ChannelData.Id) || !ObjectId.TryParse(ChannelData.Id, out _))
{
ChannelData.Id = ObjectId.GenerateNewId().ToString();
}
await _channelsCollection.InsertOneAsync(ChannelData);
return ChannelData;
}
/// <summary>
/// Adiciona vários canais de uma vez
/// </summary>
public async Task<IEnumerable<ChannelData>> AddManyAsync(IEnumerable<ChannelData> channels)
{
if (channels == null || !channels.Any())
return new List<ChannelData>();
var channelsList = channels.ToList();
// Gera novos IDs para o MongoDB se necessário
foreach (var ChannelData in channelsList)
{
if (string.IsNullOrEmpty(ChannelData.Id) || !ObjectId.TryParse(ChannelData.Id, out _))
{
ChannelData.Id = ObjectId.GenerateNewId().ToString();
}
}
// Verifica canais existentes pelo ID do YouTube
var youtubeIds = channelsList.Select(c => c.YoutubeId).ToList();
var existingChannels = await _channelsCollection
.Find(c => youtubeIds.Contains(c.YoutubeId))
.ToListAsync();
var existingYoutubeIds = existingChannels.Select(c => c.YoutubeId).ToHashSet();
var newChannels = channelsList.Where(c => !existingYoutubeIds.Contains(c.YoutubeId)).ToList();
if (newChannels.Any())
await _channelsCollection.InsertManyAsync(newChannels);
return newChannels;
}
/// <summary>
/// Atualiza um canal existente
/// </summary>
public async Task<bool> UpdateAsync(ChannelData ChannelData)
{
if (string.IsNullOrEmpty(ChannelData.Id) || !ObjectId.TryParse(ChannelData.Id, out _))
return false;
var result = await _channelsCollection.ReplaceOneAsync(
c => c.Id == ChannelData.Id,
ChannelData,
new ReplaceOptions { IsUpsert = false });
return result.IsAcknowledged && result.ModifiedCount > 0;
}
/// <summary>
/// Remove um canal pelo ID do MongoDB
/// </summary>
public async Task<bool> DeleteAsync(string id)
{
if (!ObjectId.TryParse(id, out _))
return false;
var result = await _channelsCollection.DeleteOneAsync(c => c.Id == id);
return result.IsAcknowledged && result.DeletedCount > 0;
}
/// <summary>
/// Remove um canal pelo ID do YouTube
/// </summary>
public async Task<bool> DeleteByYoutubeIdAsync(string youtubeId)
{
var result = await _channelsCollection.DeleteOneAsync(c => c.YoutubeId == youtubeId);
return result.IsAcknowledged && result.DeletedCount > 0;
}
/// <summary>
/// Busca canais com base em um termo de pesquisa no título ou descrição
/// </summary>
public async Task<IEnumerable<ChannelData>> SearchAsync(string searchTerm)
{
if (string.IsNullOrWhiteSpace(searchTerm))
return await GetAllAsync();
var filter = Builders<ChannelData>.Filter.Text(searchTerm);
return await _channelsCollection.Find(filter).ToListAsync();
}
/// <summary>
/// Obtém canais selecionados (IsSelected = true)
/// </summary>
public async Task<IEnumerable<ChannelData>> GetSelectedAsync()
{
return await _channelsCollection.Find(c => c.IsSelected).ToListAsync();
}
/// <summary>
/// Marca ou desmarca um canal como selecionado
/// </summary>
public async Task<bool> SetSelectedStatusAsync(string id, bool isSelected)
{
if (!ObjectId.TryParse(id, out _))
return false;
var update = Builders<ChannelData>.Update.Set(c => c.IsSelected, isSelected);
var result = await _channelsCollection.UpdateOneAsync(c => c.Id == id, update);
return result.IsAcknowledged && result.ModifiedCount > 0;
}
/// <summary>
/// Converte ChannelResponse para ChannelData
/// </summary>
public ChannelData ConvertFromResponse(ChannelResponse channelResponse)
{
if (channelResponse == null)
return null;
return new ChannelData
{
YoutubeId = channelResponse.Id,
Title = channelResponse.Title,
Description = channelResponse.Description,
ThumbnailUrl = channelResponse.ThumbnailUrl,
PublishedAt = channelResponse.PublishedAt,
SubscriberCount = channelResponse.SubscriberCount,
VideoCount = channelResponse.VideoCount,
IsSelected = channelResponse.IsSelected
};
}
/// <summary>
/// Converte ChannelData para ChannelResponse
/// </summary>
public ChannelResponse ConvertToResponse(ChannelData ChannelData)
{
if (ChannelData == null)
return null;
return new ChannelResponse
{
Id = ChannelData.YoutubeId,
Title = ChannelData.Title,
Description = ChannelData.Description,
ThumbnailUrl = ChannelData.ThumbnailUrl,
PublishedAt = ChannelData.PublishedAt,
SubscriberCount = ChannelData.SubscriberCount,
VideoCount = ChannelData.VideoCount,
IsSelected = ChannelData.IsSelected
};
}
}
}