using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using LehrerApp.Core.Models;
namespace LehrerApp.Desktop.Services;
public sealed class SchoolWeatherException(string message) : Exception(message);
/// Client für das serverseitige Schulstandort-/Wetterprofil. Liest URL und Token je
/// Aufruf, damit ein Login oder Serverwechsel in den Einstellungen sofort berücksichtigt wird.
public sealed class SchoolWeatherService(HttpClient http, SyncSettingsService syncSettings)
{
public bool IsAvailable => !string.IsNullOrWhiteSpace(syncSettings.ServerUrl) && syncSettings.IsLoggedIn;
public async Task GetLocationAsync(CancellationToken cancellationToken = default)
{
using var response = await SendAsync(HttpMethod.Get, "/api/school/location", null, cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound) return null;
await EnsureSuccessAsync(response);
return await response.Content.ReadFromJsonAsync(cancellationToken);
}
public async Task SaveLocationAsync(SchoolLocationRequest location,
CancellationToken cancellationToken = default)
{
using var response = await SendAsync(HttpMethod.Put, "/api/school/location", location, cancellationToken);
await EnsureSuccessAsync(response);
return await response.Content.ReadFromJsonAsync(cancellationToken)
?? throw new SchoolWeatherException("Der Server hat keine Standortdaten zurückgegeben.");
}
public async Task GetWeatherAsync(CancellationToken cancellationToken = default)
{
using var response = await SendAsync(HttpMethod.Get, "/api/school/weather", null, cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound) return null;
await EnsureSuccessAsync(response);
return await response.Content.ReadFromJsonAsync(cancellationToken);
}
private async Task SendAsync(HttpMethod method, string path, object? body,
CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(syncSettings.ServerUrl) || !syncSettings.IsLoggedIn)
throw new SchoolWeatherException("Bitte zuerst im Reiter „Synchronisation“ am Server anmelden.");
using var request = new HttpRequestMessage(method, new Uri(new Uri(syncSettings.ServerUrl), path));
var token = syncSettings.GetToken();
if (token is not null)
request.Headers.Authorization = new("Bearer", token);
if (body is not null) request.Content = JsonContent.Create(body);
try { return await http.SendAsync(request, cancellationToken); }
catch (HttpRequestException)
{
throw new SchoolWeatherException("Der LehrerApp-Server ist nicht erreichbar.");
}
}
private static async Task EnsureSuccessAsync(HttpResponseMessage response)
{
if (response.IsSuccessStatusCode) return;
if (response.StatusCode == HttpStatusCode.Unauthorized)
throw new SchoolWeatherException("Die Server-Anmeldung ist abgelaufen. Bitte erneut anmelden.");
try
{
using var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (document.RootElement.TryGetProperty("detail", out var detail) &&
!string.IsNullOrWhiteSpace(detail.GetString()))
throw new SchoolWeatherException(detail.GetString()!);
}
catch (JsonException) { }
throw new SchoolWeatherException("Der Schulstandort konnte nicht gespeichert werden.");
}
}