using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ClaudeDo.Data.Git;

namespace ClaudeDo.Ui.ViewModels.Modals;

public sealed partial class WorktreeNodeViewModel : ViewModelBase
{
    public required string Name { get; init; }
    public string? Status { get; init; }
    public bool IsDirectory { get; init; }
    public ObservableCollection<WorktreeNodeViewModel> Children { get; } = new();
}

public sealed partial class WorktreeModalViewModel : ViewModelBase
{
    private readonly GitService _git;

    public ObservableCollection<WorktreeNodeViewModel> Root { get; } = new();

    [ObservableProperty] private string _worktreePath = "";

    // Set by the view (same pattern as DiffModalViewModel.CloseAction)
    public Action? CloseAction { get; set; }

    public WorktreeModalViewModel(GitService git)
    {
        _git = git;
    }

    [RelayCommand]
    private void Close() => CloseAction?.Invoke();

    public async Task LoadAsync(CancellationToken ct = default)
    {
        Root.Clear();

        string stdout;
        try { stdout = await _git.GetStatusPorcelainAsync(WorktreePath, ct); }
        catch { return; }

        if (string.IsNullOrWhiteSpace(stdout)) return;

        var dirs = new Dictionary<string, WorktreeNodeViewModel>(StringComparer.Ordinal);

        foreach (var line in stdout.Split('\n', StringSplitOptions.RemoveEmptyEntries))
        {
            if (line.Length < 4) continue;

            // porcelain format: XY<space>path  (XY = two-char status)
            var xy = line[..2];
            // Pick staged char first, fall back to unstaged
            var statusChar = xy[0] != ' ' ? xy[0] : xy[1];
            var status = statusChar != ' ' ? statusChar.ToString() : null;
            var path = line[3..].Trim().Replace('\\', '/');

            var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
            if (segments.Length == 0) continue;

            WorktreeNodeViewModel? parent = null;
            var accumulated = "";
            for (var i = 0; i < segments.Length - 1; i++)
            {
                accumulated = accumulated.Length == 0 ? segments[i] : accumulated + "/" + segments[i];
                if (!dirs.TryGetValue(accumulated, out var dir))
                {
                    dir = new WorktreeNodeViewModel { Name = segments[i], IsDirectory = true };
                    dirs[accumulated] = dir;
                    if (parent == null) Root.Add(dir);
                    else parent.Children.Add(dir);
                }
                parent = dir;
            }

            var leaf = new WorktreeNodeViewModel
            {
                Name = segments[^1],
                Status = status,
                IsDirectory = false
            };
            if (parent == null) Root.Add(leaf);
            else parent.Children.Add(leaf);
        }
    }
}
