using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.Models; using PSTW_CentralSystem.Areas.MMS; using System.Linq; using QuestPDF.Fluent; using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator; using System.Globalization; using System.IO; namespace PSTW_CentralSystem.Areas.MMS.Controllers { [Area("MMS")] //[Authorize(Policy = "RoleModulePolicy")] public class MarineController(MMSSystemContext context) : Controller { private readonly MMSSystemContext _context = context; private const string PhotoBasePath = @"\\192.168.12.42\images\marine\manual_tarball"; public IActionResult Index() { return View(); } public IActionResult TarBallForm() { var marineTarballs = _context.MarineTarballs .Where(t => t.StationID != "1")//remove unusable data (to be modified later to delete) .Select(t => new { t.Id, Date = t.DateSample.ToString("yyyy/MM/dd"), Station = t.StationID }) .ToList(); // Debugging foreach (var item in marineTarballs) { Console.WriteLine($"Date: {item.Date}, Station: {item.Station}"); } return View(marineTarballs); } public IActionResult GenerateReport(int id) { return GeneratePdfResponse(id, true); } public IActionResult ViewPDF(int id) { return GeneratePdfResponse(id, false); } private IActionResult GeneratePdfResponse(int id, bool forceDownload) { Console.WriteLine($"Requested ID in {(forceDownload ? "GenerateReport" : "ViewPDF")}: {id}"); try { // 1. Fetch core data from database var tarballData = (from marine in _context.MarineTarballs join station in _context.MarineStations on marine.StationID equals station.StationID join state in _context.States on station.StateID equals state.StateID where marine.Id == id select new { state.StateName, marine.StationID, station.LocationName, marine.Longitude, marine.Latitude, marine.DateSample, marine.TimeSample, marine.ClassifyID, TarBallYes = marine.ClassifyID != "NO", TarBallNo = marine.ClassifyID == "NO", IsSand = marine.ClassifyID == "SD", IsNonSandy = marine.ClassifyID == "NS", IsCoquina = marine.ClassifyID == "CO" }).FirstOrDefault(); if (tarballData == null) return NotFound("Record not found"); // 2. Get photos from station folder (with date matching) var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd"); var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID); var stationImages = new List(); if (Directory.Exists(stationFolder)) { var allImages = Directory.GetFiles(stationFolder) .Where(f => { var fileName = Path.GetFileNameWithoutExtension(f); var parts = fileName.Split('_'); return parts.Length >= 3 && parts[0] == tarballData.StationID && parts[1] == sampleDateString && (f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) && IsImageValid(f); }) .ToList(); // Define image priority order var imageTypesInOrder = new List { "LEFTSIDECOASTALVIEW", "RIGHTSIDECOASTALVIEW", "DRAWINGVERTICALLINES", "DRAWINGHORIZONTALLINES", "OPTIONAL01", "OPTIONAL02", "OPTIONAL03", "OPTIONAL04" }; // Sort logic (same as before) bool hasValidFormat = allImages.Any(f => imageTypesInOrder.Any(t => Path.GetFileNameWithoutExtension(f).ToUpper().Contains(t))); if (hasValidFormat) { stationImages = allImages .OrderBy(f => { var fileName = Path.GetFileNameWithoutExtension(f).ToUpper(); var typeIndex = imageTypesInOrder.FindIndex(t => fileName.Contains(t)); return typeIndex >= 0 ? typeIndex : int.MaxValue; }) .ThenBy(f => f) .Take(8) .ToList(); } else { stationImages = allImages .OrderBy(f => f) .Take(8) .ToList(); Console.WriteLine($"WARNING: No images matched keywords. Sorted alphabetically."); } } // Validate minimum images if (stationImages.Count < 4) { return StatusCode(400, $"Minimum 4 images required for {tarballData.DateSample:yyyy/MM/dd}. Found: {stationImages.Count}"); } // 3. Generate PDF var pdf = new TarBallPDF( tarballData.StateName, tarballData.StationID, tarballData.LocationName, tarballData.Longitude, tarballData.Latitude, tarballData.DateSample, tarballData.TimeSample, tarballData.ClassifyID, tarballData.TarBallYes, tarballData.TarBallNo, tarballData.IsSand, tarballData.IsNonSandy, tarballData.IsCoquina, stationImages.Count > 0 ? stationImages[0] : null, stationImages.Count > 1 ? stationImages[1] : null, stationImages.Count > 2 ? stationImages[2] : null, stationImages.Count > 3 ? stationImages[3] : null, stationImages.Count > 4 ? stationImages[4] : null, stationImages.Count > 5 ? stationImages[5] : null, stationImages.Count > 6 ? stationImages[6] : null, stationImages.Count > 7 ? stationImages[7] : null ).GeneratePdf(); // 4. Return file return forceDownload ? File(pdf, "application/pdf", $"TbReport_{tarballData.StationID}_{tarballData.DateSample:yyyyMMdd}.pdf") : File(pdf, "application/pdf"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return StatusCode(500, $"PDF generation failed: {ex.Message}"); } } private static List GetStationPhotos(string folderPath) { try { if (!Directory.Exists(folderPath)) { Console.WriteLine($"Folder not found: {folderPath}"); return []; // Return empty list } // Get ALL .jpg/.png files (no date sorting) return Directory.GetFiles(folderPath) .Where(f => f.EndsWith(".jpg") || f.EndsWith(".png")) .OrderBy(f => f) // Optional: Sort alphabetically .ToList(); } catch (Exception ex) { Console.WriteLine($"Error fetching photos: {ex.Message}"); return []; // Return empty list on error } } private bool IsImageValid(string imagePath) { try { using (var image = System.Drawing.Image.FromFile(imagePath)) return true; } catch { Console.WriteLine($"Invalid image skipped: {imagePath}"); return false; } } } }