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
}
};
}
}