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 OnlineInboxSettingsViewModel : ViewModelBase
{
    private readonly IWorkerClient _worker;
    private readonly OnlineLoginService _loginService;

    [ObservableProperty] private bool _enabled;
    [ObservableProperty] private string _apiBaseUrl = "";
    [ObservableProperty] private string _authority = "";
    [ObservableProperty] private string _clientId = "";
    [ObservableProperty] private string _scopes = "openid offline_access";
    [ObservableProperty] private string _redirectUri = "http://localhost:8765/callback";
    [ObservableProperty] private int _pollIntervalSeconds = 60;
    [ObservableProperty] private bool _signedIn;
    [ObservableProperty] private bool _isBusy;
    [ObservableProperty] private string _statusMessage = "";

    public OnlineInboxSettingsViewModel(IWorkerClient worker, OnlineLoginService loginService)
    {
        _worker = worker;
        _loginService = loginService;
    }

    public async Task LoadAsync()
    {
        IsBusy = true;
        StatusMessage = "";
        try
        {
            var dto = await _worker.GetOnlineInboxStateAsync();
            if (dto is null)
            {
                StatusMessage = Loc.T("vm.onlineInbox.workerOffline");
                return;
            }

            Enabled = dto.Enabled;
            ApiBaseUrl = dto.ApiBaseUrl;
            Authority = dto.Authority;
            ClientId = dto.ClientId;
            Scopes = dto.Scopes;
            RedirectUri = dto.RedirectUri;
            SignedIn = dto.SignedIn;
            PollIntervalSeconds = dto.PollIntervalSeconds;
        }
        finally { IsBusy = false; }
    }

    // Persists the Online Inbox config. Exceptions propagate so callers (the modal's Apply)
    // can surface and halt; the per-tab Save button wraps this and shows its own message.
    public async Task SaveAsync()
    {
        IsBusy = true;
        StatusMessage = "";
        try
        {
            await _worker.SetOnlineInboxConfigAsync(new OnlineInboxConfigInputDto(
                Enabled,
                ApiBaseUrl,
                PollIntervalSeconds,
                Authority,
                ClientId,
                Scopes,
                RedirectUri));
            StatusMessage = Loc.T("vm.onlineInbox.saved");
        }
        finally { IsBusy = false; }
    }

    [RelayCommand]
    private async Task Save()
    {
        try { await SaveAsync(); }
        catch (Exception ex) { StatusMessage = Loc.T("vm.onlineInbox.saveFailed", ex.Message); }
    }

    [RelayCommand]
    private async Task SignIn()
    {
        IsBusy = true;
        StatusMessage = "";
        try
        {
            var result = await _loginService.LoginAsync(Authority, ClientId, Scopes, RedirectUri);
            if (!result.Success)
            {
                StatusMessage = Loc.T("vm.onlineInbox.signInFailed", result.Error ?? "Unknown error");
                return;
            }

            await _worker.SetOnlineInboxAuthAsync(result.RefreshToken!);
            SignedIn = true;
            StatusMessage = result.Warning == "missing-user-role"
                ? Loc.T("vm.onlineInbox.signedInNoRole")
                : Loc.T("vm.onlineInbox.signedIn");
        }
        catch (Exception ex)
        {
            StatusMessage = Loc.T("vm.onlineInbox.signInFailed", ex.Message);
        }
        finally { IsBusy = false; }
    }

    [RelayCommand]
    private async Task SignOut()
    {
        IsBusy = true;
        StatusMessage = "";
        try
        {
            await _worker.ClearOnlineInboxAuthAsync();
            SignedIn = false;
            StatusMessage = Loc.T("vm.onlineInbox.signedOut");
        }
        catch (Exception ex)
        {
            StatusMessage = Loc.T("vm.onlineInbox.signOutFailed", ex.Message);
        }
        finally { IsBusy = false; }
    }
}
