using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.ViewModels.Islands;

namespace ClaudeDo.Ui.ViewModels;

public sealed partial class IslandsShellViewModel : ViewModelBase
{
    public ListsIslandViewModel Lists { get; }
    public TasksIslandViewModel Tasks { get; }
    public DetailsIslandViewModel Details { get; }
    public WorkerClient Worker { get; }

    public string ConnectionText =>
        Worker.IsConnected ? "Online"
        : Worker.IsReconnecting ? "Connecting…"
        : "Offline";

    public bool IsOffline => !Worker.IsConnected && !Worker.IsReconnecting;

    [ObservableProperty]
    private double _windowWidth = 1280;

    public bool ShowDetails => WindowWidth >= 1100;
    public bool ShowLists => WindowWidth >= 780;

    [RelayCommand]
    private void FocusSearch() => Lists.RequestFocusSearch();

    [RelayCommand]
    private void FocusAddTask() => Tasks.RequestFocusAddTask();

    public async Task ToggleSelectedDoneAsync()
    {
        if (Tasks.SelectedTask is { } row)
            await Tasks.ToggleDoneCommand.ExecuteAsync(row);
    }

    partial void OnWindowWidthChanged(double value)
    {
        OnPropertyChanged(nameof(ShowDetails));
        OnPropertyChanged(nameof(ShowLists));
    }

    public IslandsShellViewModel(
        ListsIslandViewModel lists,
        TasksIslandViewModel tasks,
        DetailsIslandViewModel details,
        WorkerClient worker)
    {
        Lists = lists; Tasks = tasks; Details = details; Worker = worker;
        Lists.SelectionChanged += (_, _) => Tasks.LoadForList(Lists.SelectedList);
        Tasks.SelectionChanged += (_, _) => Details.Bind(Tasks.SelectedTask);
        Tasks.TasksChanged     += (_, _) => _ = Lists.RefreshCountsAsync();
        Details.CloseDetail = () => Tasks.SelectedTask = null;
        Details.DeleteFromList = row =>
        {
            Tasks.LoadForList(Lists.SelectedList);
            _ = Lists.RefreshCountsAsync();
            return System.Threading.Tasks.Task.CompletedTask;
        };
        Worker.PropertyChanged += (_, e) =>
        {
            if (e.PropertyName is nameof(WorkerClient.IsConnected) or nameof(WorkerClient.IsReconnecting))
            {
                OnPropertyChanged(nameof(ConnectionText));
                OnPropertyChanged(nameof(IsOffline));
            }
        };
        _ = Lists.LoadAsync();
    }
}
