using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;

namespace CamBooth.App.Features.PhotoPrismUpload;

/// <summary>
/// Service für die Token-basierte Authentifizierung bei PhotoPrism.
/// </summary>
public class PhotoPrismAuthService
{
    private readonly AppSettingsService _appSettings;
    private readonly Logger _logger;
    private readonly HttpClient _httpClient;
    
    private string _accessToken = string.Empty;
    private bool _isAuthenticated = false;

    public bool IsAuthenticated => _isAuthenticated;
    public string AccessToken => _accessToken;

    public PhotoPrismAuthService(AppSettingsService appSettings, Logger logger)
    {
        _appSettings = appSettings;
        _logger = logger;
        _httpClient = new HttpClient { Timeout = TimeSpan.FromMinutes(5) };
    }

    /// <summary>
    /// Authentifiziert sich bei PhotoPrism mit Username/Password oder API-Key.
    /// </summary>
    public async Task<bool> AuthenticateAsync()
    {
        try
        {
            _logger.Debug("Starte PhotoPrism-Authentifizierung...");

            if (!ValidateConfiguration()) 
                return false;

            // Authentifizierung mit API-Key, falls vorhanden
            if (!string.IsNullOrWhiteSpace(_appSettings.PhotoPrismApiKey))
            {
                _logger.Info("Authentifiziere mit API-Key...");
                _accessToken = _appSettings.PhotoPrismApiKey;
                _isAuthenticated = true;
                _logger.Info("Authentifizierung mit API-Key erfolgreich!");
                return true;
            }

            // Fallback: Login mit Username/Password
            return await AuthenticateWithCredentialsAsync();
        }
        catch (Exception ex)
        {
            _logger.Error($"Fehler bei der PhotoPrism-Authentifizierung: {ex.Message}");
            return false;
        }
    }

    private async Task<bool> AuthenticateWithCredentialsAsync()
    {
        try
        {
            _logger.Info("Authentifiziere mit Username/Password...");

            var loginRequest = new
            {
                username = _appSettings.PhotoPrismUsername,
                password = _appSettings.PhotoPrismPassword
            };

            var requestContent = new StringContent(
                JsonSerializer.Serialize(loginRequest),
                Encoding.UTF8,
                "application/json");

            var response = await _httpClient.PostAsync(
                $"{_appSettings.PhotoPrismApiUrl}/api/v1/auth/login",
                requestContent);

            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                _logger.Error($"Login fehlgeschlagen ({response.StatusCode}): {errorContent}");
                
                if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    _logger.Error("❌ API-Endpoint nicht gefunden (404)");
                    _logger.Error($"   Überprüfe die PhotoPrism API-URL: {_appSettings.PhotoPrismApiUrl}");
                    _logger.Error($"   (Stelle sicher, dass es eine PhotoPrism-Instanz ist, nicht Lychee!)");
                }
                else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    _logger.Error("❌ Falsche Credentials (401)");
                    _logger.Error($"   Username: {_appSettings.PhotoPrismUsername}");
                    _logger.Error($"   Überprüfe Passwort und Benutzer");
                }
                
                return false;
            }

            var jsonResponse = await response.Content.ReadAsStringAsync();
            using var document = JsonDocument.Parse(jsonResponse);
            var root = document.RootElement;

            if (root.TryGetProperty("access_token", out var tokenProp))
            {
                _accessToken = tokenProp.GetString() ?? string.Empty;
                _isAuthenticated = true;
                _logger.Info("Authentifizierung mit Credentials erfolgreich!");
                return true;
            }

            _logger.Error("Kein Access-Token in der Authentifizierungsantwort gefunden");
            return false;
        }
        catch (Exception ex)
        {
            _logger.Error($"Fehler bei der Credentials-Authentifizierung: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// Meldet sich von PhotoPrism ab.
    /// </summary>
    public async Task LogoutAsync()
    {
        try
        {
            if (!_isAuthenticated)
                return;

            var request = new HttpRequestMessage(HttpMethod.Post, $"{_appSettings.PhotoPrismApiUrl}/api/v1/auth/logout");
            request.Headers.Add("X-Auth-Token", _accessToken);

            await _httpClient.SendAsync(request);
            _isAuthenticated = false;
            _accessToken = string.Empty;
            _logger.Info("Von PhotoPrism abgemeldet");
        }
        catch (Exception ex)
        {
            _logger.Error($"Fehler beim Abmelden: {ex.Message}");
        }
    }

    private bool ValidateConfiguration()
    {
        if (string.IsNullOrWhiteSpace(_appSettings.PhotoPrismApiUrl))
        {
            _logger.Error("PhotoPrism API-URL ist nicht konfiguriert");
            return false;
        }

        var hasApiKey = !string.IsNullOrWhiteSpace(_appSettings.PhotoPrismApiKey);
        var hasCredentials = !string.IsNullOrWhiteSpace(_appSettings.PhotoPrismUsername) &&
                            !string.IsNullOrWhiteSpace(_appSettings.PhotoPrismPassword);

        if (!hasApiKey && !hasCredentials)
        {
            _logger.Error("Weder API-Key noch Credentials für PhotoPrism konfiguriert");
            return false;
        }

        return true;
    }

    public void Dispose()
    {
        _httpClient?.Dispose();
    }
}
