using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text; using System.Text.Json; using SilverLabs.Website.Models; namespace SilverLabs.Website.Services; public class DeveloperApplicationService { private readonly HttpClient _httpClient; private readonly ILogger _logger; public DeveloperApplicationService(HttpClient httpClient, ILogger logger) { _httpClient = httpClient; _logger = logger; } public async Task CheckUsernameAsync(string username) { try { var response = await _httpClient.GetAsync($"/api/auth/check-username/{Uri.EscapeDataString(username)}"); if (!response.IsSuccessStatusCode) return false; var result = await response.Content.ReadFromJsonAsync(); return result.TryGetProperty("available", out var available) && available.GetBoolean(); } catch (Exception ex) { _logger.LogError(ex, "Error checking username availability for {Username}", username); return false; } } public async Task<(bool Success, string Message, string? Token)> SubmitApplicationAsync(DeveloperApplication application) { try { // 1. Register user on SilverDESK var registerPayload = new { username = application.DesiredUsername, email = application.Email, password = application.Password, fullName = application.FullName }; var registerResponse = await _httpClient.PostAsJsonAsync("/api/auth/register", registerPayload); if (!registerResponse.IsSuccessStatusCode) { var errorBody = await registerResponse.Content.ReadAsStringAsync(); _logger.LogError("SilverDESK registration failed: {StatusCode} - {Body}", registerResponse.StatusCode, errorBody); var friendlyMessage = ParseRegistrationError(errorBody); return (false, friendlyMessage, null); } var authResult = await registerResponse.Content.ReadFromJsonAsync(); var token = authResult.GetProperty("token").GetString(); // 2. Create ticket using the user's own JWT var ticketBody = FormatTicketBody(application); var ticketPayload = new { Subject = $"[Developer Program] {application.Role} Application - {application.FullName}", Description = ticketBody, Priority = "Medium", Category = "Developer Program" }; var ticketRequest = new HttpRequestMessage(HttpMethod.Post, "/api/tickets"); ticketRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); ticketRequest.Content = JsonContent.Create(ticketPayload); var ticketResponse = await _httpClient.SendAsync(ticketRequest); if (!ticketResponse.IsSuccessStatusCode) { var errorBody = await ticketResponse.Content.ReadAsStringAsync(); _logger.LogError("Failed to create ticket: {StatusCode} - {Body}", ticketResponse.StatusCode, errorBody); // User was created but ticket failed — still return success with a note return (true, "Your account has been created, but we had trouble submitting your application ticket. Please log in to SilverDESK and create a support ticket.", token); } _logger.LogInformation("Developer application submitted for {Email} as {Role} — user registered and ticket created", application.Email, application.Role); return (true, "Application submitted successfully! Your SilverDESK account has been created.", token); } catch (Exception ex) { _logger.LogError(ex, "Error submitting developer application for {Email}", application.Email); return (false, "Unable to connect to the application service. Please try again later.", null); } } private static string ParseRegistrationError(string errorBody) { try { var error = JsonSerializer.Deserialize(errorBody); if (error.TryGetProperty("message", out var message)) { var msg = message.GetString() ?? ""; if (msg.Contains("Username already exists", StringComparison.OrdinalIgnoreCase)) return "That username is already taken. Please choose a different one."; if (msg.Contains("Email already exists", StringComparison.OrdinalIgnoreCase)) return "An account with that email already exists."; if (msg.Contains("Password", StringComparison.OrdinalIgnoreCase)) return msg; return msg; } } catch { } return "Something went wrong creating your account. Please try again later."; } private static string FormatTicketBody(DeveloperApplication app) { var sb = new StringBuilder(); sb.AppendLine("## Developer Program Application"); sb.AppendLine(); sb.AppendLine($"**Role:** {app.Role}"); sb.AppendLine($"**Full Name:** {app.FullName}"); sb.AppendLine($"**Email:** {app.Email}"); sb.AppendLine($"**Desired Username:** {app.DesiredUsername}"); sb.AppendLine($"**Timezone:** {app.Timezone}"); sb.AppendLine(); sb.AppendLine($"**Platforms:** {string.Join(", ", app.Platforms)}"); sb.AppendLine(); if (app.Role == ApplicationRole.Developer && !string.IsNullOrWhiteSpace(app.Skills)) { sb.AppendLine("**Skills & Experience:**"); sb.AppendLine(app.Skills); sb.AppendLine(); } sb.AppendLine("**Motivation:**"); sb.AppendLine(app.Motivation); return sb.ToString(); } }