using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Json; using LittleShop.Client.Models; using Microsoft.Extensions.Logging; namespace LittleShop.Client.Services; public class AuthenticationService : IAuthenticationService { private readonly HttpClient _httpClient; private readonly ILogger _logger; private string? _currentToken; private DateTime? _tokenExpiry; public AuthenticationService(HttpClient httpClient, ILogger logger) { _httpClient = httpClient; _logger = logger; } public async Task> LoginAsync(string username, string password) { try { var request = new LoginRequest { Username = username, Password = password }; var response = await _httpClient.PostAsJsonAsync("api/auth/login", request); if (response.IsSuccessStatusCode) { var loginResponse = await response.Content.ReadFromJsonAsync(); if (loginResponse != null) { SetToken(loginResponse.Token); return ApiResponse.Success(loginResponse); } } var error = await response.Content.ReadAsStringAsync(); return ApiResponse.Failure( error ?? "Login failed", response.StatusCode); } catch (Exception ex) { _logger.LogError(ex, "Login failed"); return ApiResponse.Failure( ex.Message, System.Net.HttpStatusCode.InternalServerError); } } public async Task> RefreshTokenAsync() { if (string.IsNullOrEmpty(_currentToken)) { return ApiResponse.Failure( "No token to refresh", System.Net.HttpStatusCode.Unauthorized); } try { _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _currentToken); var response = await _httpClient.PostAsync("api/auth/refresh", null); if (response.IsSuccessStatusCode) { var loginResponse = await response.Content.ReadFromJsonAsync(); if (loginResponse != null) { SetToken(loginResponse.Token); return ApiResponse.Success(loginResponse); } } return ApiResponse.Failure( "Token refresh failed", response.StatusCode); } catch (Exception ex) { _logger.LogError(ex, "Token refresh failed"); return ApiResponse.Failure( ex.Message, System.Net.HttpStatusCode.InternalServerError); } } public void SetToken(string token) { _currentToken = token; _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); // Parse token to get expiry try { var handler = new JwtSecurityTokenHandler(); var jsonToken = handler.ReadJwtToken(token); _tokenExpiry = jsonToken.ValidTo; } catch (Exception ex) { _logger.LogWarning(ex, "Failed to parse token expiry"); _tokenExpiry = DateTime.UtcNow.AddHours(1); // Default to 1 hour } } public string? GetToken() => _currentToken; public bool IsAuthenticated() { return !string.IsNullOrEmpty(_currentToken) && _tokenExpiry.HasValue && _tokenExpiry.Value > DateTime.UtcNow; } public void Logout() { _currentToken = null; _tokenExpiry = null; _httpClient.DefaultRequestHeaders.Authorization = null; } }