using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json.Serialization; using Model; namespace Web.Services; public class CardNotesGraphQLService { private readonly AuthService _authService; private readonly string _graphqlEndpoint; private readonly HttpClient _http; private readonly NetworkStatusService _networkStatus; public CardNotesGraphQLService(HttpClient http, NetworkStatusService networkStatus, AuthService authService) { _http = http; _networkStatus = networkStatus; _authService = authService; _graphqlEndpoint = http.BaseAddress != null && http.BaseAddress.Port == 5256 ? "/graphql" : "http://localhost:5256/graphql"; } public async Task IsApiOnlineAsync() { if (!_networkStatus.IsOnline) return false; try { var request = new GraphQLRequest { Query = "query { __typename }" }; var response = await SendGraphQLAsync(request); return response != null; } catch { return false; } } public async Task GetNoteAsync(string cardName) { if (!_networkStatus.IsOnline || !_authService.IsLoggedIn) return string.Empty; try { var request = new GraphQLRequest { Query = @"query GetCardNote($cardName: String!) { note(cardName: $cardName) { username cardName note } }", Variables = new Dictionary { ["cardName"] = cardName } }; var response = await SendGraphQLAsync(request); return response?.Data?.Note?.Note ?? string.Empty; } catch (Exception ex) { Console.WriteLine($"[WARNING] Failed to fetch note for {cardName}: {ex.Message}"); return string.Empty; } } public async Task SaveNoteAsync(string cardName, string note) { if (!_networkStatus.IsOnline || !_authService.IsLoggedIn) return false; try { var request = new GraphQLRequest { Query = @"mutation SaveCardNote($cardName: String!, $note: String!) { saveNote(cardName: $cardName, note: $note) { username cardName note } }", Variables = new Dictionary { ["cardName"] = cardName, ["note"] = note } }; var response = await SendGraphQLAsync(request); return response?.Data?.SaveNote != null; } catch (Exception ex) { Console.WriteLine($"[WARNING] Failed to save note for {cardName}: {ex.Message}"); return false; } } private async Task?> SendGraphQLAsync(GraphQLRequest request) { async Task SendToUrlAsync(string url) { var httpRequest = new HttpRequestMessage(HttpMethod.Post, url) { Content = JsonContent.Create(request) }; if (!string.IsNullOrEmpty(_authService.AuthToken)) httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _authService.AuthToken); return await _http.SendAsync(httpRequest); } try { var httpResponse = await SendToUrlAsync(_graphqlEndpoint); if (httpResponse.IsSuccessStatusCode) return await httpResponse.Content.ReadFromJsonAsync>(); if (_graphqlEndpoint == "/graphql") { var fallbackResponse = await SendToUrlAsync("http://localhost:5256/graphql"); if (fallbackResponse.IsSuccessStatusCode) return await fallbackResponse.Content.ReadFromJsonAsync>(); } } catch { try { var fallbackResponse = await SendToUrlAsync("http://localhost:5256/graphql"); if (fallbackResponse.IsSuccessStatusCode) return await fallbackResponse.Content.ReadFromJsonAsync>(); } catch { } } return null; } public class GraphQLRequest { [JsonPropertyName("query")] public string Query { get; set; } = string.Empty; [JsonPropertyName("variables")] public Dictionary? Variables { get; set; } } public class GraphQLResponse { [JsonPropertyName("data")] public T? Data { get; set; } [JsonPropertyName("errors")] public List? Errors { get; set; } } public class GraphQLError { [JsonPropertyName("message")] public string Message { get; set; } = string.Empty; } public class GetNoteData { [JsonPropertyName("note")] public CardNote? Note { get; set; } } public class SaveNoteData { [JsonPropertyName("saveNote")] public CardNote? SaveNote { get; set; } } }