using Microsoft.AspNetCore.Mvc; using BankSampahApp.Models; using BankSampahApp.Services; using System.Diagnostics; namespace BankSampahApp.Controllers; /// /// Controller utama untuk halaman Home dengan .NET 9 best practices /// [Route("")] [Route("[controller]")] public class HomeController : Controller { private readonly ILogger _logger; private readonly IHomeService _homeService; private readonly IAppConfigurationService _appConfig; /// /// Constructor dengan dependency injection /// /// Logger untuk logging /// Service untuk logic bisnis home /// Application configuration service public HomeController( ILogger logger, IHomeService homeService, IAppConfigurationService appConfig) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _homeService = homeService ?? throw new ArgumentNullException(nameof(homeService)); _appConfig = appConfig ?? throw new ArgumentNullException(nameof(appConfig)); } /// /// Halaman utama aplikasi /// /// View dengan HomeViewModel [HttpGet("")] [HttpGet("Index")] [ResponseCache(Duration = 300, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new string[] { })] public async Task Index() { try { using var scope = _logger.BeginScope(new Dictionary { ["Action"] = nameof(Index), ["Controller"] = nameof(HomeController) }); _logger.LogInformation("Loading home page"); var stopwatch = Stopwatch.StartNew(); var model = await _homeService.GetHomeViewModelAsync(); stopwatch.Stop(); _logger.LogInformation("Home page loaded successfully in {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds); // Add performance metrics to ViewBag for debugging if (_appConfig.DevelopmentSettings.EnablePerformanceMetrics) { ViewBag.LoadTime = stopwatch.ElapsedMilliseconds; } return View(model); } catch (Exception ex) { _logger.LogError(ex, "Error loading home page"); // Return error view with fallback data var fallbackModel = CreateFallbackViewModel(); return View(fallbackModel); } } /// /// Halaman kebijakan privasi /// /// Privacy view [HttpGet("Privacy")] [ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Any)] public IActionResult Privacy() { _logger.LogInformation("Privacy page accessed"); return View(); } /// /// Halaman error dengan enhanced error handling /// /// Error view dengan ErrorViewModel [HttpGet("Error")] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { var requestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; // Get exception details from HttpContext items (set by GlobalExceptionFilter) var exception = HttpContext.Items["Exception"] as Exception; var storedRequestId = HttpContext.Items["RequestId"] as string; _logger.LogWarning("Error page accessed. RequestId: {RequestId}, HasException: {HasException}", requestId, exception != null); var model = new ErrorViewModel { RequestId = storedRequestId ?? requestId }; // Add additional debug info in development if (_appConfig.ShowDetailedExceptions) { ViewBag.ExceptionMessage = exception?.Message; ViewBag.ExceptionType = exception?.GetType().Name; } return View(model); } /// /// API endpoint untuk mendapatkan statistik (untuk AJAX calls) /// /// JSON dengan statistik terkini [HttpGet("api/statistics")] [ResponseCache(Duration = 900, Location = ResponseCacheLocation.Any)] public async Task GetStatistics() { try { _logger.LogDebug("API statistics endpoint called"); var statistics = await _homeService.GetStatisticsAsync(); return Json(new { success = true, data = statistics, timestamp = DateTime.UtcNow }); } catch (Exception ex) { _logger.LogError(ex, "Error fetching statistics via API"); return Json(new { success = false, error = "Unable to fetch statistics", timestamp = DateTime.UtcNow }); } } /// /// Create fallback view model saat terjadi error /// /// Fallback HomeViewModel private HomeViewModel CreateFallbackViewModel() { _logger.LogWarning("Creating fallback view model due to error"); return new HomeViewModel { Title = _appConfig.ApplicationName, Subtitle = "Layanan sedang dalam pemeliharaan, silakan coba lagi nanti.", Features = new List(), Statistics = new StatisticsModel { TotalUsers = 0, WasteCollected = 0, RewardsDistributed = 0, EnvironmentImpact = 0 } }; } }