using System.Collections.ObjectModel;
using System.Windows.Controls;
using ClaudeDo.Installer.Checks;
using ClaudeDo.Installer.Core;
using ClaudeDo.Installer.Localization;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClaudeDo.Installer.Pages.SystemCheckPage;

public partial class SystemCheckPageViewModel : ObservableObject, IInstallerPage
{
    private readonly InstallContext _context;
    private readonly ClaudeHelpLauncher _claudeHelpLauncher;
    private SystemCheckPageView? _view;
    private bool _hasStarted;

    public string Title => TrExtension.Localizer?["installer.systemCheck.title"] ?? "System Check";
    public string Icon => "";
    public int Order => 1;
    public bool ShowInWizard => true;
    public bool ShowInSettings => false;
    public UserControl View => _view ??= new SystemCheckPageView { DataContext = this };

    public CheckListViewModel Checks { get; }

    // Pass-through to the shared check-run logic — kept so this page's UI/tests can bind
    // directly on it, matching the pre-extraction API.
    public ObservableCollection<CheckRowViewModel> Rows => Checks.Rows;
    public bool IsRunning => Checks.IsRunning;
    public bool HasRun => Checks.HasRun;
    public bool HasBlockingError => Checks.HasBlockingError;
    public string Summary => Checks.Summary;
    public IAsyncRelayCommand RunChecksCommand => Checks.RunChecksCommand;

    public bool BlocksNavigation => Checks.IsRunning || Checks.HasBlockingError;

    [ObservableProperty] private string? _claudeHelpError;

    public bool ClaudeCliOk =>
        Checks.LastReport?.Results.FirstOrDefault(r => r.Id == ClaudeCliCheck.CheckId)?.Status == CheckStatus.Ok;

    public bool ClaudeAuthFailed =>
        Checks.LastReport?.Results.FirstOrDefault(r => r.Id == ClaudeAuthCheck.CheckId)?.Status == CheckStatus.Failed;

    public bool CanStartClaudeHelp => ClaudeCliOk && !ClaudeAuthFailed;

    public string ClaudeHelpTooltip
    {
        get
        {
            var loc = TrExtension.Localizer;
            if (!ClaudeCliOk)
                return loc?["installer.systemCheck.claudeHelp.tooltip.cliMissing"] ?? "The Claude CLI was not found.";
            if (ClaudeAuthFailed)
                return loc?["installer.systemCheck.claudeHelp.tooltip.notLoggedIn"] ?? "Claude is not logged in.";
            return loc?["installer.systemCheck.claudeHelp.tooltip.ready"]
                   ?? "Start an interactive Claude session to help troubleshoot your setup.";
        }
    }

    public SystemCheckPageViewModel(
        InstallContext context,
        Func<EnvironmentCheckService> checkServiceFactory,
        ClaudeHelpLauncher claudeHelpLauncher)
    {
        _context = context;
        _claudeHelpLauncher = claudeHelpLauncher;
        Checks = new CheckListViewModel(context, checkServiceFactory);
        // The wizard listens for PropertyChanged on this page to re-evaluate "Next" — bubble
        // any change from the composed check list up so a live recheck can flip it back, and so
        // the Claude-Help gating re-reads the fresh report.
        Checks.PropertyChanged += (_, _) =>
        {
            OnPropertyChanged(nameof(BlocksNavigation));
            OnPropertyChanged(nameof(ClaudeCliOk));
            OnPropertyChanged(nameof(ClaudeAuthFailed));
            OnPropertyChanged(nameof(CanStartClaudeHelp));
            OnPropertyChanged(nameof(ClaudeHelpTooltip));
            StartClaudeHelpCommand.NotifyCanExecuteChanged();
        };
    }

    public Task LoadAsync()
    {
        if (!_hasStarted)
        {
            _hasStarted = true;
            _ = Checks.RunChecksCommand.ExecuteAsync(null);
        }
        return Task.CompletedTask;
    }

    public Task ApplyAsync() => Task.CompletedTask;

    public bool Validate() => !HasBlockingError;

    [RelayCommand(CanExecute = nameof(CanStartClaudeHelp))]
    private async Task StartClaudeHelpAsync()
    {
        if (Checks.LastReport is null) return;

        ClaudeHelpError = null;
        var result = await _claudeHelpLauncher.LaunchAsync(Checks.LastReport, _context, CancellationToken.None);
        if (!result.Success)
        {
            ClaudeHelpError = TrExtension.Localizer?.Get("installer.systemCheck.claudeHelp.error", result.ErrorMessage ?? "")
                              ?? $"Could not start the Claude session: {result.ErrorMessage}";
        }
    }
}
