using GestionIntegral.Api.Dtos.Distribucion; using GestionIntegral.Api.Services.Distribucion; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; namespace GestionIntegral.Api.Controllers.Distribucion { [Route("api/canillas/{idCanilla}/paradas")] // Anidado bajo canillas [ApiController] [Authorize] public class CambiosParadaController : ControllerBase { private readonly ICambioParadaService _paradaService; private readonly ILogger _logger; private const string PermisoGestionarParadas = "CG007"; public CambiosParadaController(ICambioParadaService paradaService, ILogger logger) { _paradaService = paradaService; _logger = logger; } private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc); private int? GetCurrentUserId() { if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId; _logger.LogWarning("No se pudo obtener el UserId del token JWT en CambiosParadaController."); return null; } // GET: api/canillas/{idCanilla}/paradas [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task GetParadasPorCanilla(int idCanilla) { // Podría usarse CG001 (Ver Canilla) o CG007 para ver el historial de paradas if (!TienePermiso("CG001") && !TienePermiso(PermisoGestionarParadas)) return Forbid(); var paradas = await _paradaService.ObtenerPorCanillaAsync(idCanilla); return Ok(paradas); } // POST: api/canillas/{idCanilla}/paradas [HttpPost] [ProducesResponseType(typeof(CambioParadaDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task CreateParada(int idCanilla, [FromBody] CreateCambioParadaDto createDto) { if (!TienePermiso(PermisoGestionarParadas)) return Forbid(); if (!ModelState.IsValid) return BadRequest(ModelState); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (paradaDto, error) = await _paradaService.CrearNuevaParadaAsync(idCanilla, createDto, userId.Value); if (error != null) return BadRequest(new { message = error }); if (paradaDto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la parada."); // La ruta para "GetById" podría estar en otro controlador si decides separar los endpoints de "paradas individuales" // Por ahora, asumimos que habrá un endpoint para obtener una parada por su ID de registro. return CreatedAtAction(nameof(GetParadaById), new { idCanilla = idCanilla, idRegistroParada = paradaDto.IdRegistro }, paradaDto); } // GET: api/canillas/{idCanilla}/paradas/{idRegistroParada} (o api/paradas/{idRegistroParada}) // Este endpoint es opcional, pero útil si necesitas obtener una parada específica por su ID de registro [HttpGet("{idRegistroParada:int}", Name = "GetParadaById")] [ProducesResponseType(typeof(CambioParadaDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetParadaById(int idCanilla, int idRegistroParada) // idCanilla es parte de la ruta base { if (!TienePermiso("CG001") && !TienePermiso(PermisoGestionarParadas)) return Forbid(); var parada = await _paradaService.ObtenerPorIdAsync(idRegistroParada); if (parada == null || parada.IdCanilla != idCanilla) return NotFound(new { message = "Registro de parada no encontrado para este canillita."}); return Ok(parada); } // PUT: api/paradas/{idRegistroParada}/cerrar (Ruta ejemplo para cerrar una parada) // O podrías usar PUT api/canillas/{idCanilla}/paradas/{idRegistroParada} y que el DTO solo tenga VigenciaH [HttpPut("~/api/paradas/{idRegistroParada}/cerrar")] // Ruta a nivel raíz para paradas si se edita por IdRegistro [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task CerrarVigenciaParada(int idRegistroParada, [FromBody] UpdateCambioParadaDto updateDto) { if (!TienePermiso(PermisoGestionarParadas)) return Forbid(); if (!ModelState.IsValid) return BadRequest(ModelState); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (exito, error) = await _paradaService.CerrarParadaAsync(idRegistroParada, updateDto, userId.Value); if (!exito) { if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error }); return BadRequest(new { message = error }); } return NoContent(); } // DELETE: api/paradas/{idRegistroParada} [HttpDelete("~/api/paradas/{idRegistroParada}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteParada(int idRegistroParada) { if (!TienePermiso(PermisoGestionarParadas)) return Forbid(); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (exito, error) = await _paradaService.EliminarParadaAsync(idRegistroParada, userId.Value); if (!exito) { if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error }); return BadRequest(new { message = error }); } return NoContent(); } } }