using Microsoft.AspNetCore.Mvc; using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.Areas.MMS.Models; using System.IO; using System.Linq; using PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator; using QuestPDF.Fluent; namespace PSTW_CentralSystem.Areas.MMS.Controllers { [Area("MMS")] public class MarineController : Controller { private readonly MMSSystemContext _context;//Used in TarBallForm and GeneratePdfResponse to query the database. private readonly NetworkShareAccess _networkAccessService;//used in GetImage and GeneratePdfResponse private const string PhotoBasePath = "\\\\192.168.12.42\\images\\marine\\manual_tarball";//used in GetImage and GeneratePdfResponse public MarineController(MMSSystemContext context, NetworkShareAccess networkAccessService) { _context = context; _networkAccessService = networkAccessService; } public IActionResult Index() { return View(); } public IActionResult TarBallForm()//Queries the database and returns a view with tarball data { try { var marineTarballs = _context.MarineTarballs .Where(t => t.StationID != "1") // To remove unusable data with invalid stationID .Select(t => new { t.Id, Date = t.DateSample.ToString("yyyy/MM/dd"), Station = t.StationID }) .ToList(); Console.WriteLine($"Marine Tarballs Count: {marineTarballs.Count}"); return View(marineTarballs); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return StatusCode(500, "An error occurred while loading the data."); } } [HttpGet] // Explicitly mark as a GET endpoint public IActionResult TestCredentials() { try { // Use the EXACT same path/credentials as in Program.cs var testService = new NetworkShareAccess( @"\\192.168.12.42\images\marine\manual_tarball", "installer", "mms@pstw" ); testService.ConnectToNetworkPath(); testService.DisconnectFromNetworkShare(); return Ok("Network credentials and path are working correctly!"); } catch (Exception ex) { // Log the full error (including stack trace) Console.WriteLine($"TestCredentials failed: {ex}"); return StatusCode(500, $"Credentials test failed: {ex.Message}"); } } public IActionResult GetImage(string fileName) { try { // Connect to the network path _networkAccessService.ConnectToNetworkPath(); string imagePath = Path.Combine(PhotoBasePath, fileName); if (System.IO.File.Exists(imagePath)) { byte[] imageBytes = System.IO.File.ReadAllBytes(imagePath); return File(imageBytes, "image/jpeg"); } else { return NotFound("Image not found."); } } catch (Exception ex) { Console.WriteLine($"Error retrieving image: {ex.Message}"); return StatusCode(500, "Error retrieving image."); } finally { // Disconnect from the network path _networkAccessService.DisconnectFromNetworkShare(); } } public IActionResult GenerateReport(int id)//calls GeneratePdfResponse to generate a PDF for inline viewing { 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 { // Connect to the network path _networkAccessService.ConnectToNetworkPath();//------------------ // 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", marine.OptionalName1, marine.OptionalName2, marine.OptionalName3, marine.OptionalName4, marine.FirstSampler }).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 Dictionary(); 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" }; // Match images to their types foreach (var imageType in imageTypesInOrder) { var matchedImage = allImages.FirstOrDefault(f => Path.GetFileNameWithoutExtension(f).ToUpper().Contains(imageType)); if (matchedImage != null) { stationImages[imageType] = matchedImage; } } } // Validate mandatory images var mandatoryImages = new List { "LEFTSIDECOASTALVIEW", "RIGHTSIDECOASTALVIEW", "DRAWINGVERTICALLINES", "DRAWINGHORIZONTALLINES" }; foreach (var mandatoryImage in mandatoryImages) { if (!stationImages.ContainsKey(mandatoryImage)) { return StatusCode(400, $"Missing mandatory image: {mandatoryImage}"); } } // 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.ContainsKey("LEFTSIDECOASTALVIEW") ? stationImages["LEFTSIDECOASTALVIEW"] : null, stationImages.ContainsKey("RIGHTSIDECOASTALVIEW") ? stationImages["RIGHTSIDECOASTALVIEW"] : null, stationImages.ContainsKey("DRAWINGVERTICALLINES") ? stationImages["DRAWINGVERTICALLINES"] : null, stationImages.ContainsKey("DRAWINGHORIZONTALLINES") ? stationImages["DRAWINGHORIZONTALLINES"] : null, stationImages.ContainsKey("OPTIONAL01") ? stationImages["OPTIONAL01"] : null, stationImages.ContainsKey("OPTIONAL02") ? stationImages["OPTIONAL02"] : null, stationImages.ContainsKey("OPTIONAL03") ? stationImages["OPTIONAL03"] : null, stationImages.ContainsKey("OPTIONAL04") ? stationImages["OPTIONAL04"] : null, tarballData.OptionalName1, tarballData.OptionalName2, tarballData.OptionalName3, tarballData.OptionalName4, tarballData.FirstSampler ).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}"); } finally { // Disconnect from the network path _networkAccessService.DisconnectFromNetworkShare(); } } 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; } } } }