using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClaudeDo.Ui.ViewModels.Modals.Settings;

public sealed partial class TicketSettingsTabViewModel : ViewModelBase
{
    /// <summary>
    /// Der Aus-Schalter der gesamten Ticketsystem-Anbindung in der UI — hier auf <c>true</c>
    /// für die Reaktivierung, wie bei <c>SettingsModalViewModel.ShowOnlineInbox</c>.
    ///
    /// Pausiert am 2026-08-27: die Bandel-API war unter dem eingetragenen Hostnamen nicht
    /// erreichbar (Verbindung aktiv abgelehnt — vermutlich fehlende IIS-Hostname-Bindung oder
    /// falscher Port, siehe deploy/deploy-iis-winrm.ps1). Solange das offen ist, würde der Tab
    /// nur eine Einrichtung anbieten, die nicht funktionieren kann.
    ///
    /// Der Schalter versteckt drei Einstiegspunkte: diesen Settings-Tab, das Ticket-Projekt-
    /// Dropdown in den Listen-Einstellungen und den Kontextmenü-Eintrag zum Importieren.
    /// Gespeicherte Werte (Base-URL, PAT, verknüpfte Projekte) bleiben unangetastet und greifen
    /// beim Umlegen sofort wieder.
    /// </summary>
    public const bool FeatureEnabled = false;

    private readonly IWorkerClient _worker;

    [ObservableProperty] private string _apiBaseUrl = "";
    [ObservableProperty] private string _token = "";
    [ObservableProperty]
    [NotifyPropertyChangedFor(nameof(TokenPlaceholder))]
    private bool _tokenSet;
    [ObservableProperty] private bool _isBusy;
    [ObservableProperty] private string _statusMessage = "";

    // Never shows the stored token — TicketSettingsDto only ever carries the bool.
    public string TokenPlaceholder => TokenSet ? Loc.T("settings.tickets.tokenSet") : "";

    public TicketSettingsTabViewModel(IWorkerClient worker) => _worker = worker;

    public async Task LoadAsync()
    {
        var dto = await _worker.GetTicketSettingsAsync();
        if (dto is null)
        {
            StatusMessage = Loc.T("vm.tickets.workerOffline");
            return;
        }
        ApiBaseUrl = dto.ApiBaseUrl ?? "";
        TokenSet = dto.TokenSet;
    }

    public async Task SaveAsync()
    {
        await _worker.SetTicketApiBaseUrlAsync(ApiBaseUrl);
        if (!string.IsNullOrWhiteSpace(Token))
        {
            await _worker.SetTicketTokenAsync(Token);
            Token = "";
            TokenSet = true;
        }
    }

    [RelayCommand]
    private async Task TestConnection()
    {
        IsBusy = true;
        StatusMessage = "";
        try
        {
            await SaveAsync();
            var result = await _worker.TestTicketConnectionAsync();
            if (result is null || !result.Ok)
            {
                StatusMessage = result?.Error ?? Loc.T("vm.tickets.workerOffline");
                return;
            }

            var missing = RequiredScopes.Where(s => !result.Scopes.Contains(s)).ToList();
            StatusMessage = missing.Count == 0
                ? Loc.T("vm.tickets.connectionOk", result.UserName!)
                : Loc.T("vm.tickets.connectionMissingScopes", result.UserName!, string.Join(", ", missing));
        }
        finally
        {
            IsBusy = false;
        }
    }

    [RelayCommand]
    private async Task ClearToken()
    {
        await _worker.ClearTicketTokenAsync();
        Token = "";
        TokenSet = false;
        StatusMessage = Loc.T("vm.tickets.tokenCleared");
    }

    // Ohne diese drei Scopes scheitert entweder der Import oder die Statusrueckmeldung —
    // der mit Abstand haeufigste Konfigurationsfehler, deshalb wird er beim Testen benannt
    // statt nur geloggt.
    private static readonly string[] RequiredScopes =
    [
        "pat:projects:read",
        "pat:board:read",
        "pat:tickets:write",
    ];
}
