using Dapper; using SIGCM.Domain.Entities; using SIGCM.Infrastructure.Data; namespace SIGCM.Infrastructure.Repositories; public class ClientRepository { private readonly IDbConnectionFactory _db; public ClientRepository(IDbConnectionFactory db) { _db = db; } // Búsqueda inteligente con protección de nulos public async Task> SearchAsync(string query) { using var conn = _db.CreateConnection(); var sql = @" SELECT TOP 10 Id, ISNULL(Name, 'Sin Nombre') as Name, ISNULL(DniOrCuit, '') as DniOrCuit, Email, Phone, Address FROM Clients WHERE Name LIKE @Query OR DniOrCuit LIKE @Query ORDER BY Name"; return await conn.QueryAsync(sql, new { Query = $"%{query}%" }); } // Asegurar existencia (Upsert) public async Task EnsureClientExistsAsync(string name, string dni) { using var conn = _db.CreateConnection(); var existingId = await conn.ExecuteScalarAsync( "SELECT Id FROM Clients WHERE DniOrCuit = @Dni", new { Dni = dni }); if (existingId.HasValue) { await conn.ExecuteAsync("UPDATE Clients SET Name = @Name WHERE Id = @Id", new { Name = name, Id = existingId }); return existingId.Value; } else { var sql = @" INSERT INTO Clients (Name, DniOrCuit) VALUES (@Name, @Dni); SELECT CAST(SCOPE_IDENTITY() as int);"; return await conn.QuerySingleAsync(sql, new { Name = name, Dni = dni }); } } // Obtener todos con estadísticas (ISNULL agregado para seguridad) public async Task> GetAllWithStatsAsync() { using var conn = _db.CreateConnection(); var sql = @" SELECT c.Id as id, ISNULL(c.Name, 'Sin Nombre') as name, ISNULL(c.DniOrCuit, 'S/D') as dniOrCuit, ISNULL(c.Email, 'Sin correo') as email, ISNULL(c.Phone, 'Sin teléfono') as phone, (SELECT COUNT(1) FROM Listings l WHERE l.ClientId = c.Id) as totalAds, ISNULL((SELECT SUM(AdFee) FROM Listings l WHERE l.ClientId = c.Id), 0) as totalSpent FROM Clients c ORDER BY c.Name"; return await conn.QueryAsync(sql); } public async Task UpdateAsync(Client client) { using var conn = _db.CreateConnection(); var sql = @" UPDATE Clients SET Name = @Name, DniOrCuit = @DniOrCuit, Email = @Email, Phone = @Phone, Address = @Address WHERE Id = @Id"; await conn.ExecuteAsync(sql, client); } public async Task GetClientSummaryAsync(int clientId) { using var conn = _db.CreateConnection(); var sql = @" SELECT c.Id, c.Name, c.DniOrCuit, c.Email, c.Phone, c.Address, (SELECT COUNT(1) FROM Listings WHERE ClientId = c.Id) as TotalAds, ISNULL((SELECT SUM(AdFee) FROM Listings WHERE ClientId = c.Id), 0) as TotalInvested, (SELECT MAX(CreatedAt) FROM Listings WHERE ClientId = c.Id) as LastAdDate, (SELECT COUNT(1) FROM Listings WHERE ClientId = c.Id AND Status = 'Published') as ActiveAds, ISNULL(( SELECT TOP 1 cat.Name FROM Listings l JOIN Categories cat ON l.CategoryId = cat.Id WHERE l.ClientId = c.Id GROUP BY cat.Name ORDER BY COUNT(l.Id) DESC ), 'N/A') as PreferredCategory FROM Clients c WHERE c.Id = @Id"; return await conn.QuerySingleOrDefaultAsync(sql, new { Id = clientId }); } }