using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using Postall.Domain; using Postall.Domain.Entities; using Postall.Infra.MongoDB.Settings; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Postall.Infra.MongoDB.Repositories { public class UserSocialRepository : IUserSocialRepository { private readonly IMongoCollection _userSocialCollection; public UserSocialRepository(IOptions mongoDbSettings) { var client = new MongoClient(mongoDbSettings.Value.ConnectionString); var database = client.GetDatabase(mongoDbSettings.Value.DatabaseName); _userSocialCollection = database.GetCollection(mongoDbSettings.Value.UserSocialCollectionName); // Cria índice para userId (deve ser único) var indexKeysDefinition = Builders.IndexKeys .Ascending(u => u.UserId); _userSocialCollection.Indexes.CreateOne(new CreateIndexModel(indexKeysDefinition, new CreateIndexOptions { Unique = true })); } /// /// Obtém todos os dados sociais dos usuários /// public async Task> GetAllAsync() { return await _userSocialCollection.Find(u => true).ToListAsync(); } /// /// Obtém os dados sociais pelo ID do MongoDB /// public async Task GetByIdAsync(string id) { if (!ObjectId.TryParse(id, out _)) return null; return await _userSocialCollection.Find(u => u.Id == ObjectId.Parse(id)).FirstOrDefaultAsync(); } /// /// Obtém os dados sociais pelo ID do usuário /// public async Task GetByUserIdAsync(string userId) { return await _userSocialCollection.Find(u => u.UserId == userId).FirstOrDefaultAsync(); } /// /// Obtém os dados sociais pelo token do Google /// public async Task GetByGoogleTokenAsync(string googleToken) { return await _userSocialCollection.Find(u => u.GoogleToken == googleToken).FirstOrDefaultAsync(); } /// /// Adiciona novos dados sociais de usuário /// public async Task AddAsync(UserSocialData userSocialData) { var existingUserSocial = await GetByUserIdAsync(userSocialData.UserId); if (existingUserSocial != null) return existingUserSocial; if (userSocialData.Id == ObjectId.Empty) { userSocialData.Id = ObjectId.GenerateNewId(); } try { await _userSocialCollection.InsertOneAsync(userSocialData); } catch (MongoWriteException ex) { if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) { return await GetByUserIdAsync(userSocialData.UserId); } else { throw; } } return userSocialData; } /// /// Atualiza os dados sociais de um usuário existente /// public async Task UpdateAsync(UserSocialData userSocialData) { if (userSocialData.Id == ObjectId.Empty) return false; var result = await _userSocialCollection.ReplaceOneAsync( u => u.Id == userSocialData.Id, userSocialData, new ReplaceOptions { IsUpsert = false }); return result.IsAcknowledged && result.ModifiedCount > 0; } /// /// Atualiza os dados sociais de um usuário existente /// public async Task UpdateOneAsync(UserSocialData userSocialData) { if (userSocialData.Id == ObjectId.Empty) return false; var result = await _userSocialCollection.ReplaceOneAsync( u => u.Id == userSocialData.Id, userSocialData, new ReplaceOptions { IsUpsert = false }); return result.IsAcknowledged && result.ModifiedCount > 0; } /// /// Atualiza ou insere os dados sociais de um usuário /// public async Task UpsertAsync(UserSocialData userSocialData) { var existingData = await GetByUserIdAsync(userSocialData.UserId); if (existingData != null) { userSocialData.Id = existingData.Id; await _userSocialCollection.ReplaceOneAsync( u => u.Id == existingData.Id, userSocialData, new ReplaceOptions { IsUpsert = true }); return userSocialData; } else { return await AddAsync(userSocialData); } } /// /// Remove os dados sociais pelo ID do MongoDB /// public async Task DeleteAsync(string id) { if (!ObjectId.TryParse(id, out _)) return false; var result = await _userSocialCollection.DeleteOneAsync(u => u.Id == ObjectId.Parse(id)); return result.IsAcknowledged && result.DeletedCount > 0; } /// /// Remove os dados sociais pelo ID do usuário /// public async Task DeleteByUserIdAsync(string userId) { var result = await _userSocialCollection.DeleteOneAsync(u => u.UserId == userId); return result.IsAcknowledged && result.DeletedCount > 0; } /// /// Atualiza apenas o token do Google para um usuário /// public async Task UpdateGoogleTokenAsync(string userId, string googleToken) { var update = Builders.Update.Set(u => u.GoogleToken, googleToken); var result = await _userSocialCollection.UpdateOneAsync( u => u.UserId == userId, update, new UpdateOptions { IsUpsert = true }); return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null); } /// /// Atualiza apenas o token do Facebook para um usuário /// public async Task UpdateFacebookTokenAsync(string userId, FacebookToken facebookToken) { var update = Builders.Update.Set(u => u.FacebookToken, facebookToken); var result = await _userSocialCollection.UpdateOneAsync( u => u.UserId == userId, update, new UpdateOptions { IsUpsert = true }); return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null); } public async Task UpdateOneAsync(string userId, UpdateDefinition update) { var result = await _userSocialCollection.UpdateOneAsync( x => x.UserId == userId, update, new UpdateOptions { IsUpsert = true }); return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null); } } }