using Microsoft.AspNetCore.Mvc; using MieSystem.Models; using MieSystem.Models.ViewModels; using MieSystem.Services; namespace MieSystem.Controllers { public class ExpedientesController : Controller { private static List _expedientes = new List(); //private static int _idCounter = 1; private readonly IWebHostEnvironment _hostingEnvironment; private readonly ExpedienteService expedienteService; public ExpedientesController(ExpedienteService expedienteService, IWebHostEnvironment hostingEnvironment) { _hostingEnvironment = hostingEnvironment; this.expedienteService = expedienteService; } // GET: Expedientes public async Task Index() { var lst = await expedienteService.GetAllAsync(); _expedientes = [.. lst]; return View(); } // GET: Expedientes/GetDashboardStats [HttpGet] public IActionResult GetDashboardStats() { var totalNinos = _expedientes.Count; var mesActual = DateTime.Now.Month; var cumpleanerosMes = _expedientes .Where(e => e.FechaNacimiento.Month == mesActual) .Count(); var mayores14 = _expedientes .Where(e => { var edad = DateTime.Now.Year - e.FechaNacimiento.Year; if (DateTime.Now.Month < e.FechaNacimiento.Month || (DateTime.Now.Month == e.FechaNacimiento.Month && DateTime.Now.Day < e.FechaNacimiento.Day)) { edad--; } return edad > 14; }) .Count(); return Json(new { totalNinos, cumpleanerosMes, mayores14 }); } // GET: Expedientes/GetExpedientes [HttpGet] public IActionResult GetExpedientes(int page = 1, int pageSize = 10) { var query = _expedientes .Where(e => e.Activo) .OrderBy(e => e.Apellidos) .ThenBy(e => e.Nombre); var totalItems = query.Count(); var totalPages = (int)Math.Ceiling(totalItems / (double)pageSize); var expedientes = query .Skip((page - 1) * pageSize) .Take(pageSize) .Select(e => new ExpedienteViewModel { Id = e.Id, Nombre = e.Nombre, Apellidos = e.Apellidos, FechaNacimiento = e.FechaNacimiento, Sexo = e.Sexo, NombreResponsable = e.NombreResponsable, FotoUrl = ExisteFoto(e.FotoUrl) }) .ToList(); return Json(new { items = expedientes, totalItems, totalPages, currentPage = page }); } // GET: Expedientes/Create public IActionResult Create() { ViewData["IsEdit"] = false; return PartialView("_CreateOrEdit", new ExpedienteViewModel()); } // POST: Expedientes/Create [HttpPost] public async Task Create(ExpedienteViewModel model) { ModelState.Remove("Foto"); ModelState.Remove("FotoUrl"); ModelState.Remove("Observaciones"); if (ModelState.IsValid) { string fotoUrl = "/images/default-avatar.png"; // Procesar la foto si existe if (model.Foto != null && model.Foto.Length > 0) { var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads", "fotos"); // Crear directorio si no existe if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } var fileName = Guid.NewGuid().ToString() + Path.GetExtension(model.Foto.FileName); var filePath = Path.Combine(uploadsFolder, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await model.Foto.CopyToAsync(stream); } fotoUrl = $"/uploads/fotos/{fileName}"; } // Crear nuevo expediente var expediente = new Expediente { Nombre = model.Nombre, Apellidos = model.Apellidos, FechaNacimiento = model.FechaNacimiento, NombrePadre = model.NombrePadre, NombreMadre = model.NombreMadre, NombreResponsable = model.NombreResponsable, ParentescoResponsable = model.ParentescoResponsable, Sexo = model.Sexo, Direccion = model.Direccion, Telefono = model.Telefono, Observaciones = model.Observaciones, FotoUrl = fotoUrl, FechaCreacion = DateTime.Now, FechaActualizacion = DateTime.Now, Activo = true }; try { //await _expedienteRepository.CreateAsync(expediente); await expedienteService.SaveAsync(expediente); return Json(new { success = true, message = "Expediente creado exitosamente" }); } catch (Exception ex) { return Json(new { success = false, message = ex.Message }); } } return Json(new { success = false, message = "Error en los datos del formulario" }); } // GET: Expedientes/Edit/5 public IActionResult Edit(int id) { var expediente = _expedientes.FirstOrDefault(e => e.Id == id); if (expediente == null) { return NotFound(); } var model = new ExpedienteViewModel { Id = expediente.Id, Nombre = expediente.Nombre, Apellidos = expediente.Apellidos, FechaNacimiento = expediente.FechaNacimiento, NombrePadre = expediente.NombrePadre, NombreMadre = expediente.NombreMadre, NombreResponsable = expediente.NombreResponsable, ParentescoResponsable = expediente.ParentescoResponsable, Sexo = expediente.Sexo, Direccion = expediente.Direccion, Telefono = expediente.Telefono, Observaciones = expediente.Observaciones, FotoUrl = expediente.FotoUrl }; ViewData["IsEdit"] = true; return PartialView("_CreateOrEdit", model); } // POST: Expedientes/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(int id, ExpedienteViewModel model) { if (id != model.Id) { return Json(new { success = false, message = "ID no coincide" }); } ModelState.Remove("Foto"); ModelState.Remove("FotoUrl"); ModelState.Remove("Observaciones"); if (ModelState.IsValid) { //var expediente = await _expedienteRepository.GetByIdAsync(id); var expediente = await expedienteService.GetByIdAsync(id); //var expediente = _expedientes.FirstOrDefault(e => e.Id == id); if (expediente == null) { return Json(new { success = false, message = "Expediente no encontrado" }); } // Guardar la foto URL actual antes de actualizar string fotoUrlActual = expediente.FotoUrl; // Procesar nueva foto si se subió if (model.Foto != null && model.Foto.Length > 0) { var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads", "fotos"); // Crear directorio si no existe if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } var fileName = Guid.NewGuid().ToString() + Path.GetExtension(model.Foto.FileName); var filePath = Path.Combine(uploadsFolder, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await model.Foto.CopyToAsync(stream); } fotoUrlActual = $"/uploads/fotos/{fileName}"; // Opcional: eliminar foto anterior si no es la predeterminada if (!string.IsNullOrEmpty(expediente.FotoUrl) && expediente.FotoUrl != "/images/default-avatar.png") { var oldFilePath = Path.Combine(_hostingEnvironment.WebRootPath, expediente.FotoUrl.TrimStart('/')); if (System.IO.File.Exists(oldFilePath)) { System.IO.File.Delete(oldFilePath); } } } // Actualizar datos expediente.Id = id; expediente.Nombre = model.Nombre; expediente.Apellidos = model.Apellidos; expediente.FechaNacimiento = model.FechaNacimiento; expediente.NombrePadre = model.NombrePadre; expediente.NombreMadre = model.NombreMadre; expediente.NombreResponsable = model.NombreResponsable; expediente.ParentescoResponsable = model.ParentescoResponsable; expediente.Sexo = model.Sexo; expediente.Direccion = model.Direccion; expediente.Telefono = model.Telefono; expediente.Observaciones = model.Observaciones; expediente.FotoUrl = fotoUrlActual; expediente.FechaActualizacion = DateTime.Now; try { //await _expedienteRepository.UpdateAsync(expediente); await expedienteService.SaveAsync(expediente); return Json(new { success = true, message = "Expediente actualizado exitosamente" }); } catch (Exception ex) { return Json(new { success = false, message = ex.Message }); } } return Json(new { success = false, message = "Error en los datos del formulario" }); } // DELETE: Expedientes/Delete/5 /*[HttpDelete] public async Task Delete(int id) { var expediente = _expedientes.FirstOrDefault(e => e.Id == id); if (expediente == null) { return Json(new { success = false, message = "Expediente no encontrado" }); } // Eliminar foto si existe y no es la predeterminada if (!string.IsNullOrEmpty(expediente.FotoUrl) && expediente.FotoUrl != "/images/default-avatar.png") { var filePath = Path.Combine(_hostingEnvironment.WebRootPath, expediente.FotoUrl.TrimStart('/')); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); } } // Marcar como inactivo en lugar de eliminar expediente.Activo = false; expediente.FechaActualizacion = DateTime.Now; return Json(new { success = true, message = "Expediente eliminado exitosamente" }); } */ // GET: Expedientes/Details/5 (Opcional) public IActionResult Details(int id) { var expediente = _expedientes.FirstOrDefault(e => e.Id == id); if (expediente == null) { return NotFound(); } var model = new ExpedienteViewModel { Id = expediente.Id, Nombre = expediente.Nombre, Apellidos = expediente.Apellidos, FechaNacimiento = expediente.FechaNacimiento, NombrePadre = expediente.NombrePadre, NombreMadre = expediente.NombreMadre, NombreResponsable = expediente.NombreResponsable, ParentescoResponsable = expediente.ParentescoResponsable, Sexo = expediente.Sexo, Direccion = expediente.Direccion, Telefono = expediente.Telefono, Observaciones = expediente.Observaciones, FotoUrl = expediente.FotoUrl }; return View(model); } // POST: Expedientes/UploadImage [HttpPost] public async Task UploadImage(IFormFile file) { try { if (file == null || file.Length == 0) { return Json(new { success = false, message = "No se ha seleccionado ningún archivo" }); } // Validar que sea una imagen var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" }; var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant(); if (!allowedExtensions.Contains(fileExtension)) { return Json(new { success = false, message = "Formato de archivo no permitido. Solo se permiten imágenes (JPG, JPEG, PNG, GIF, BMP)" }); } // Validar tamaño máximo (ej: 5MB) var maxFileSize = 5 * 1024 * 1024; // 5MB if (file.Length > maxFileSize) { return Json(new { success = false, message = "La imagen es demasiado grande. Tamaño máximo permitido: 5MB" }); } // Crear directorio de uploads si no existe var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads", "fotos"); if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } // Generar nombre único para el archivo var fileName = Guid.NewGuid().ToString() + fileExtension; var filePath = Path.Combine(uploadsFolder, fileName); // Guardar el archivo using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } // Generar URL relativa var imageUrl = $"/uploads/fotos/{fileName}"; return Json(new { success = true, message = "Imagen subida exitosamente", imageUrl = imageUrl, fileName = fileName }); } catch (Exception ex) { return Json(new { success = false, message = $"Error al subir la imagen: {ex.Message}" }); } } public string ExisteFoto(string url) { if(string.IsNullOrEmpty(url)) return Path.Combine("images", "default-avatar.png"); var uploadsFolder = Path.Combine(_hostingEnvironment.WebRootPath, "uploads", "fotos"); string[] parts = url.Split('/'); string name = parts[^1]; string fullpath = Path.Combine(uploadsFolder, name); if (System.IO.File.Exists(fullpath)) return url; return Path.Combine("images", "default-avatar.png"); } // GET: Expedientes/DeleteImage [HttpDelete] public IActionResult DeleteImage(string imageUrl) { try { if (string.IsNullOrEmpty(imageUrl)) { return Json(new { success = false, message = "URL de imagen no proporcionada" }); } // No permitir eliminar la imagen predeterminada if (imageUrl == "/images/default-avatar.png") { return Json(new { success = false, message = "No se puede eliminar la imagen predeterminada" }); } // Construir ruta física del archivo var filePath = Path.Combine(_hostingEnvironment.WebRootPath, imageUrl.TrimStart('/')); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); return Json(new { success = true, message = "Imagen eliminada exitosamente" }); } else { return Json(new { success = false, message = "La imagen no existe" }); } } catch (Exception ex) { return Json(new { success = false, message = $"Error al eliminar la imagen: {ex.Message}" }); } } } }