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<AuthenticationService> _logger;
    private string? _currentToken;
    private DateTime? _tokenExpiry;
    
    public AuthenticationService(HttpClient httpClient, ILogger<AuthenticationService> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }
    
    public async Task<ApiResponse<LoginResponse>> 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<LoginResponse>();
                if (loginResponse != null)
                {
                    SetToken(loginResponse.Token);
                    return ApiResponse<LoginResponse>.Success(loginResponse);
                }
            }
            
            var error = await response.Content.ReadAsStringAsync();
            return ApiResponse<LoginResponse>.Failure(
                error ?? "Login failed", 
                response.StatusCode);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Login failed");
            return ApiResponse<LoginResponse>.Failure(
                ex.Message, 
                System.Net.HttpStatusCode.InternalServerError);
        }
    }
    
    public async Task<ApiResponse<LoginResponse>> RefreshTokenAsync()
    {
        if (string.IsNullOrEmpty(_currentToken))
        {
            return ApiResponse<LoginResponse>.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<LoginResponse>();
                if (loginResponse != null)
                {
                    SetToken(loginResponse.Token);
                    return ApiResponse<LoginResponse>.Success(loginResponse);
                }
            }
            
            return ApiResponse<LoginResponse>.Failure(
                "Token refresh failed", 
                response.StatusCode);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Token refresh failed");
            return ApiResponse<LoginResponse>.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;
    }
}