using BCards.Web.Services; using Microsoft.AspNetCore.Mvc; namespace BCards.Web.Controllers; [Route("page")] public class LivePageController : Controller { private readonly ILivePageService _livePageService; private readonly ILogger _logger; public LivePageController(ILivePageService livePageService, ILogger logger) { _livePageService = livePageService; _logger = logger; } [Route("{category}/{slug}")] [ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new string[] { })] public async Task Display(string category, string slug) { // Se tem parâmetro preview, redirecionar para sistema de preview if (HttpContext.Request.Query.ContainsKey("preview")) { _logger.LogInformation("Redirecting preview request for {Category}/{Slug} to UserPageController", category, slug); return RedirectToAction("Display", "UserPage", new { category = category, slug = slug, preview = HttpContext.Request.Query["preview"].ToString() }); } var livePage = await _livePageService.GetByCategoryAndSlugAsync(category, slug); if (livePage == null) { _logger.LogInformation("LivePage not found for {Category}/{Slug}, falling back to UserPageController", category, slug); // Fallback: tentar no sistema antigo return RedirectToAction("Display", "UserPage", new { category = category, slug = slug }); } // Incrementar view de forma assíncrona (não bloquear response) _ = IncrementViewSafelyAsync(livePage.Id); // Configurar ViewBag para indicar que é uma live page ViewBag.IsLivePage = true; ViewBag.PageUrl = $"https://bcards.site/page/{category}/{slug}"; ViewBag.Title = $"{livePage.DisplayName} - {livePage.Category} | BCards"; _logger.LogInformation("Serving LivePage {LivePageId} for {Category}/{Slug}", livePage.Id, category, slug); // Usar a mesma view do UserPage mas com dados da LivePage return View("~/Views/UserPage/Display.cshtml", livePage); } [Route("{category}/{slug}/link/{linkIndex}")] public async Task TrackLinkClick(string category, string slug, int linkIndex) { var livePage = await _livePageService.GetByCategoryAndSlugAsync(category, slug); if (livePage == null || linkIndex < 0 || linkIndex >= livePage.Links.Count) { return NotFound(); } var link = livePage.Links[linkIndex]; // Track click de forma assíncrona _ = IncrementLinkClickSafelyAsync(livePage.Id, linkIndex); _logger.LogInformation("Tracking click for LivePage {LivePageId} link {LinkIndex} -> {Url}", livePage.Id, linkIndex, link.Url); return Redirect(link.Url); } private async Task IncrementViewSafelyAsync(string livePageId) { try { await _livePageService.IncrementViewAsync(livePageId); } catch (Exception ex) { _logger.LogError(ex, "Failed to increment view for LivePage {LivePageId}", livePageId); } } private async Task IncrementLinkClickSafelyAsync(string livePageId, int linkIndex) { try { await _livePageService.IncrementLinkClickAsync(livePageId, linkIndex); } catch (Exception ex) { _logger.LogError(ex, "Failed to track click for LivePage {LivePageId} link {LinkIndex}", livePageId, linkIndex); } } }