using System.Collections.ObjectModel;
using ClaudeDo.Ui.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClaudeDo.Ui.ViewModels.Modals.Settings;

public sealed partial class PrimeClaudeTabViewModel : ViewModelBase
{
    private readonly IPrimeScheduleApi _api;
    private readonly HashSet<Guid> _initialIds = new();

    [ObservableProperty] private int _dailyPrepMaxTasks = 5;

    public ObservableCollection<PrimeScheduleRowViewModel> Rows { get; } = new();

    public PrimeClaudeTabViewModel(IPrimeScheduleApi api) => _api = api;

    public async Task LoadAsync()
    {
        Rows.Clear();
        _initialIds.Clear();
        var list = await _api.ListAsync();
        foreach (var dto in list)
        {
            Rows.Add(new PrimeScheduleRowViewModel(dto, isExisting: true));
            _initialIds.Add(dto.Id);
        }
    }

    public string? Validate()
    {
        foreach (var r in Rows)
        {
            if (r.DaysMask() == 0)
                return $"Schedule {r.TimeOfDay:hh\\:mm}: select at least one day.";
            if (r.TimeOfDay < TimeSpan.Zero || r.TimeOfDay >= TimeSpan.FromDays(1))
                return "Time must be between 00:00 and 23:59.";
        }
        return null;
    }

    public async Task SaveAsync()
    {
        var keepIds = Rows.Select(r => r.Id).ToHashSet();
        foreach (var removed in _initialIds.Where(id => !keepIds.Contains(id)).ToList())
            await _api.DeleteAsync(removed);
        foreach (var r in Rows)
            await _api.UpsertAsync(r.ToDto());
        _initialIds.Clear();
        foreach (var id in keepIds) _initialIds.Add(id);
    }

    [RelayCommand]
    private void AddSchedule()
    {
        var dto = new PrimeScheduleDto(
            Id: Guid.NewGuid(),
            Days: 31, // Mon–Fri
            TimeOfDay: new TimeSpan(7, 0, 0),
            Enabled: true,
            LastRunAt: null,
            PromptOverride: null);
        Rows.Add(new PrimeScheduleRowViewModel(dto, isExisting: false));
    }

    [RelayCommand]
    private void RemoveSchedule(PrimeScheduleRowViewModel? row)
    {
        if (row is null) return;
        Rows.Remove(row);
    }

    public void ApplyFiredEvent(PrimeFiredEvent evt)
    {
        var row = Rows.FirstOrDefault(r => r.Id == evt.ScheduleId);
        if (row is null) return;
        if (evt.Success) row.LastRunAt = evt.FiredAt;
    }
}
