using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using OnlyOneAccessTemplate.Services; using OnlyOneAccessTemplate.Models; using System.Text.Json; using global::OnlyOneAccessTemplate.Services; namespace OnlyOneAccessTemplate.Controllers { [Route("conversion")] public class ConversionController : BaseController { private readonly IConversionService _conversionService; public ConversionController( ISiteConfigurationService siteConfig, ILanguageService languageService, ISeoService seoService, IMemoryCache cache, IConfiguration configuration, IConversionService conversionService) : base(siteConfig, languageService, seoService, cache, configuration) { _conversionService = conversionService; } [HttpPost("submit")] public async Task Submit([FromBody] Dictionary formData) { try { // Extract basic data var language = formData.GetValueOrDefault("language", "pt"); var pageName = formData.GetValueOrDefault("pageName", "home"); var formType = formData.GetValueOrDefault("formType", "main"); // Remove system fields from form data var cleanFormData = formData .Where(kvp => !new[] { "language", "pageName", "formType", "source", "medium", "campaign" }.Contains(kvp.Key)) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Get user info var userAgent = Request.Headers.UserAgent.ToString(); var ipAddress = GetClientIpAddress(); var referrer = Request.Headers.Referer.ToString(); // Create conversion data var conversionData = new ConversionData( Language: language, PageName: pageName, FormData: cleanFormData, UserAgent: userAgent, IpAddress: ipAddress, Referrer: referrer, SessionId: GetOrCreateSessionId(), UtmParameters: ExtractUtmParameters() ); // Process conversion var success = await _conversionService.ProcessConversionAsync(conversionData); if (success) { var response = language switch { "en" => new { success = true, message = "Thank you! We received your request and will contact you soon.", redirectUrl = $"/en/thank-you" }, "es" => new { success = true, message = "¡Gracias! Recibimos tu solicitud y te contactaremos pronto.", redirectUrl = $"/es/gracias" }, _ => new { success = true, message = "Obrigado! Recebemos sua solicitação e entraremos em contato em breve.", redirectUrl = $"/obrigado" } }; return Json(response); } else { return Json(new { success = false, message = GetErrorMessage(language) }); } } catch (Exception ex) { // Log error Console.WriteLine($"Conversion error: {ex.Message}"); var language = formData.GetValueOrDefault("language", "pt"); return Json(new { success = false, message = GetErrorMessage(language) }); } } [HttpGet("thank-you")] [HttpGet("obrigado")] public IActionResult ThankYou() { ViewBag.CurrentPage = "thank-you"; SetPageSeo( "Obrigado!", "Obrigado por entrar em contato. Nossa equipe retornará em breve.", "obrigado, contato, sucesso" ); return View(); } [HttpGet("en/thank-you")] public IActionResult ThankYouEn() { ViewBag.CurrentPage = "thank-you"; SetPageSeo( "Thank You!", "Thank you for contacting us. Our team will get back to you soon.", "thank you, contact, success" ); return View("ThankYou"); } [HttpGet("es/gracias")] public IActionResult ThankYouEs() { ViewBag.CurrentPage = "thank-you"; SetPageSeo( "¡Gracias!", "Gracias por contactarnos. Nuestro equipo se pondrá en contacto contigo pronto.", "gracias, contacto, éxito" ); return View("ThankYou"); } private string GetClientIpAddress() { // Try to get real IP address var ipAddress = Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (string.IsNullOrEmpty(ipAddress)) { ipAddress = Request.Headers["X-Real-IP"].FirstOrDefault(); } if (string.IsNullOrEmpty(ipAddress)) { ipAddress = Request.HttpContext.Connection.RemoteIpAddress?.ToString(); } return ipAddress ?? "unknown"; } private string GetOrCreateSessionId() { var sessionId = HttpContext.Session.GetString("SessionId"); if (string.IsNullOrEmpty(sessionId)) { sessionId = Guid.NewGuid().ToString("N")[..16]; HttpContext.Session.SetString("SessionId", sessionId); } return sessionId; } private Dictionary ExtractUtmParameters() { var utmParams = new Dictionary(); foreach (var param in new[] { "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content" }) { if (Request.Query.ContainsKey(param)) { utmParams[param] = Request.Query[param].ToString(); } } return utmParams; } private string GetErrorMessage(string language) { return language switch { "en" => "An error occurred while processing your request. Please try again.", "es" => "Ocurrió un error al procesar tu solicitud. Por favor, inténtalo de nuevo.", _ => "Ocorreu um erro ao processar sua solicitação. Tente novamente." }; } } // Analytics Controller [Route("api/analytics")] public class AnalyticsController : ControllerBase { private readonly IConversionService _conversionService; public AnalyticsController(IConversionService conversionService) { _conversionService = conversionService; } [HttpPost("track")] public async Task Track([FromBody] JsonElement data) { try { // Extract event data var eventName = data.GetProperty("event").GetString() ?? "unknown"; var properties = new Dictionary(); if (data.TryGetProperty("data", out var dataProperty)) { foreach (var prop in dataProperty.EnumerateObject()) { properties[prop.Name] = prop.Value.ToString() ?? ""; } } // Log the event await _conversionService.LogConversionEventAsync(eventName, properties); return Ok(new { success = true }); } catch (Exception ex) { Console.WriteLine($"Analytics tracking error: {ex.Message}"); return Ok(new { success = false }); // Don't break user experience } } [HttpPost("heatmap")] public async Task Heatmap([FromBody] JsonElement data) { try { // Process heatmap data await _conversionService.LogConversionEventAsync("heatmap_data", new Dictionary { { "data", data.ToString() } }); return Ok(new { success = true }); } catch { return Ok(new { success = false }); } } [HttpPost("time")] public async Task TimeTracking([FromBody] JsonElement data) { try { // Process time tracking data await _conversionService.LogConversionEventAsync("time_tracking", new Dictionary { { "data", data.ToString() } }); return Ok(new { success = true }); } catch { return Ok(new { success = false }); } } } }