using System.Net.Http.Json;
using Microsoft.AspNetCore.Components.Authorization;
using timetracker.Shared;

namespace timetracker.Client.Services;

public class ClientAuthService : IAuthService
{
    private readonly HttpClient _http;
    private readonly AuthenticationStateProvider _authStateProvider;

    public ClientAuthService(HttpClient http, AuthenticationStateProvider authStateProvider)
    {
        _http = http;
        _authStateProvider = authStateProvider;
    }

    private HostAuthenticationStateProvider HostProvider => (HostAuthenticationStateProvider)_authStateProvider;

    public async Task<User?> LoginAsync(string username, string password)
    {
        var response = await _http.PostAsJsonAsync("api/auth/login", new { Username = username, Password = password });
        if (response.IsSuccessStatusCode)
        {
            var userInfo = await response.Content.ReadFromJsonAsync<UserInfo>();
            if (userInfo != null)
            {
                HostProvider.NotifyUserChanged(userInfo);
                return new User { Id = userInfo.Id, Username = userInfo.Username };
            }
        }
        return null;
    }

    public async Task<(User? User, string? Error)> RegisterAsync(string username, string password, string? honeypot = null)
    {
        var response = await _http.PostAsJsonAsync("api/auth/register", new { Username = username, Password = password, Honeypot = honeypot });
        if (response.IsSuccessStatusCode)
        {
            var userInfo = await response.Content.ReadFromJsonAsync<UserInfo>();
            if (userInfo != null)
            {
                HostProvider.NotifyUserChanged(userInfo);
                return (new User { Id = userInfo.Id, Username = userInfo.Username }, null);
            }
        }
        else
        {
            var error = await response.Content.ReadAsStringAsync();
            return (null, error);
        }
        return (null, "Registrierung fehlgeschlagen.");
    }

    public async Task<List<User>> GetAllUsersAsync()
    {
        return await _http.GetFromJsonAsync<List<User>>("api/users") ?? [];
    }

    public async Task DeleteUserAsync(int userId)
    {
        await _http.DeleteAsync($"api/users/{userId}");
    }

    public async Task<string?> RenameUserAsync(int userId, string newUsername)
    {
        var response = await _http.PutAsJsonAsync($"api/users/{userId}/rename", new { Username = newUsername });
        if (!response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync();
        }
        return null;
    }

    public async Task<string?> ChangePasswordAsync(int userId, string currentPassword, string newPassword)
    {
        var response = await _http.PutAsJsonAsync($"api/users/{userId}/change-password", new { CurrentPassword = currentPassword, NewPassword = newPassword });
        if (!response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync();
        }
        return null;
    }

    public async Task<(Tenant? Tenant, string? Error)> RegisterFirmAsync(RegisterFirmRequest req)
    {
        var response = await _http.PostAsJsonAsync("api/auth/register-firm", req);
        if (response.IsSuccessStatusCode)
        {
            return (new Tenant { Name = req.CompanyName, Subdomain = req.Subdomain }, null);
        }
        else
        {
            var error = await response.Content.ReadAsStringAsync();
            return (null, error);
        }
    }

    public async Task<string?> AssignTenantAsync(int userId, int? tenantId)
    {
        var response = await _http.PutAsJsonAsync($"api/users/{userId}/assign-tenant", new AssignTenantRequest(tenantId));
        if (!response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync();
        }
        return null;
    }

    public async Task<string?> ResetPasswordAsync(int userId, string newPassword)
    {
        var response = await _http.PutAsJsonAsync($"api/users/{userId}/reset-password", new ResetPasswordRequest(newPassword));
        if (!response.IsSuccessStatusCode)
        {
            return await response.Content.ReadAsStringAsync();
        }
        return null;
    }
}
