using GestionIntegral.Api.Data.Repositories.Radios; using GestionIntegral.Api.Dtos.Radios; using GestionIntegral.Api.Models.Radios; using Microsoft.Extensions.Logging; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; // using GestionIntegral.Api.Data; // Para DbConnectionFactory si se usa transacción // using System.Data; // Para IsolationLevel si se usa transacción namespace GestionIntegral.Api.Services.Radios { public class CancionService : ICancionService { private readonly ICancionRepository _cancionRepository; private readonly IRitmoRepository _ritmoRepository; private readonly ILogger _logger; public CancionService( ICancionRepository cancionRepository, IRitmoRepository ritmoRepository, ILogger logger) { _cancionRepository = cancionRepository; _ritmoRepository = ritmoRepository; _logger = logger; } private async Task MapToDto(Cancion cancion) { if (cancion == null) return null!; string? nombreRitmo = null; if (cancion.Ritmo.HasValue && cancion.Ritmo.Value > 0) { var ritmoDb = await _ritmoRepository.GetByIdAsync(cancion.Ritmo.Value); nombreRitmo = ritmoDb?.NombreRitmo; } return new CancionDto { Id = cancion.Id, Tema = cancion.Tema, CompositorAutor = cancion.CompositorAutor, Interprete = cancion.Interprete, Sello = cancion.Sello, Placa = cancion.Placa, Pista = cancion.Pista, Introduccion = cancion.Introduccion, IdRitmo = cancion.Ritmo, // Pasar el valor de cancion.Ritmo NombreRitmo = nombreRitmo, Formato = cancion.Formato, Album = cancion.Album }; } public async Task> ObtenerTodasAsync(string? temaFilter, string? interpreteFilter, int? idRitmoFilter) { var canciones = await _cancionRepository.GetAllAsync(temaFilter, interpreteFilter, idRitmoFilter); var dtos = new List(); foreach (var cancion in canciones) { dtos.Add(await MapToDto(cancion)); } return dtos; } public async Task ObtenerPorIdAsync(int id) { var cancion = await _cancionRepository.GetByIdAsync(id); return cancion == null ? null : await MapToDto(cancion); } public async Task<(CancionDto? Cancion, string? Error)> CrearAsync(CreateCancionDto createDto, int idUsuario) { if (createDto.IdRitmo.HasValue && createDto.IdRitmo.Value > 0) // Asegurar que > 0 para evitar buscar ritmo con ID 0 { if(await _ritmoRepository.GetByIdAsync(createDto.IdRitmo.Value) == null) return (null, "El ritmo seleccionado no es válido."); } if (!string.IsNullOrWhiteSpace(createDto.Tema) && !string.IsNullOrWhiteSpace(createDto.Interprete) && await _cancionRepository.ExistsByTemaAndInterpreteAsync(createDto.Tema, createDto.Interprete)) { return (null, "Ya existe una canción con el mismo tema e intérprete."); } var nuevaCancion = new Cancion { Tema = createDto.Tema, CompositorAutor = createDto.CompositorAutor, Interprete = createDto.Interprete, Sello = createDto.Sello, Placa = createDto.Placa, Pista = createDto.Pista, Introduccion = createDto.Introduccion, Ritmo = createDto.IdRitmo, // Asignar createDto.IdRitmo a la propiedad Ritmo del modelo Formato = createDto.Formato, Album = createDto.Album }; try { var cancionCreada = await _cancionRepository.CreateAsync(nuevaCancion); if (cancionCreada == null) return (null, "Error al crear la canción."); _logger.LogInformation("Canción ID {Id} creada por Usuario ID {UserId}.", cancionCreada.Id, idUsuario); return (await MapToDto(cancionCreada), null); } catch (System.Exception ex) { _logger.LogError(ex, "Error CrearAsync Cancion: {Tema}", createDto.Tema); return (null, $"Error interno: {ex.Message}"); } } public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateCancionDto updateDto, int idUsuario) { var cancionExistente = await _cancionRepository.GetByIdAsync(id); if (cancionExistente == null) return (false, "Canción no encontrada."); if (updateDto.IdRitmo.HasValue && updateDto.IdRitmo.Value > 0) // Asegurar que > 0 { if (await _ritmoRepository.GetByIdAsync(updateDto.IdRitmo.Value) == null) return (false, "El ritmo seleccionado no es válido."); } if ((!string.IsNullOrWhiteSpace(updateDto.Tema) && !string.IsNullOrWhiteSpace(updateDto.Interprete)) && (cancionExistente.Tema != updateDto.Tema || cancionExistente.Interprete != updateDto.Interprete) && await _cancionRepository.ExistsByTemaAndInterpreteAsync(updateDto.Tema!, updateDto.Interprete!, id)) { return (false, "Ya existe otra canción con el mismo tema e intérprete."); // Devolver tupla bool,string } cancionExistente.Tema = updateDto.Tema; cancionExistente.CompositorAutor = updateDto.CompositorAutor; cancionExistente.Interprete = updateDto.Interprete; cancionExistente.Sello = updateDto.Sello; cancionExistente.Placa = updateDto.Placa; cancionExistente.Pista = updateDto.Pista; cancionExistente.Introduccion = updateDto.Introduccion; cancionExistente.Ritmo = updateDto.IdRitmo; // Asignar updateDto.IdRitmo a la propiedad Ritmo del modelo cancionExistente.Formato = updateDto.Formato; cancionExistente.Album = updateDto.Album; try { var actualizado = await _cancionRepository.UpdateAsync(cancionExistente); if (!actualizado) return (false, "Error al actualizar la canción."); _logger.LogInformation("Canción ID {Id} actualizada por Usuario ID {UserId}.", id, idUsuario); return (true, null); } catch (System.Exception ex) { _logger.LogError(ex, "Error ActualizarAsync Canción ID: {Id}", id); return (false, $"Error interno: {ex.Message}"); } } public async Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario) { var cancionExistente = await _cancionRepository.GetByIdAsync(id); if (cancionExistente == null) return (false, "Canción no encontrada."); try { var eliminado = await _cancionRepository.DeleteAsync(id); if (!eliminado) return (false, "Error al eliminar la canción."); _logger.LogInformation("Canción ID {Id} eliminada por Usuario ID {UserId}.", id, idUsuario); return (true, null); } catch (System.Exception ex) { _logger.LogError(ex, "Error EliminarAsync Canción ID: {Id}", id); return (false, $"Error interno: {ex.Message}"); } } } }