using Health.Domain.Entities;

namespace Health.Application.Exercises;

public sealed record ExercisePlanItemInput(
    DateOnly ScheduledDate,
    string? ExerciseType,
    int DurationMinutes,
    bool IsRestDay);

public sealed record ExercisePlanCreateRequest(
    DateOnly StartDate,
    DateOnly EndDate,
    string? ExerciseType,
    int DurationMinutes,
    TimeOnly? ReminderTime = null);

public sealed record ExercisePlanItemDto(
    Guid Id,
    DateOnly ScheduledDate,
    string ExerciseType,
    int DurationMinutes,
    bool IsCompleted,
    DateTime? CompletedAt,
    bool IsRestDay);

public sealed record ExercisePlanDto(
    Guid Id,
    DateOnly StartDate,
    DateOnly EndDate,
    TimeOnly ReminderTime,
    DateTime CreatedAt,
    DateTime UpdatedAt,
    IReadOnlyList<ExercisePlanItemDto> Items);

public sealed record ExercisePlanSummaryDto(
    Guid Id,
    DateOnly StartDate,
    DateOnly EndDate,
    TimeOnly ReminderTime,
    DateTime CreatedAt,
    int TotalDays,
    int CompletedDays,
    IReadOnlyList<ExercisePlanItemDto> Items);

public interface IExerciseService
{
    Task<ExercisePlanDto?> GetCurrentAsync(Guid userId, CancellationToken ct);
    Task<Guid> CreateAsync(Guid userId, ExercisePlanCreateRequest request, CancellationToken ct);
    Task<Guid> CreateFromItemsAsync(Guid userId, DateOnly startDate, DateOnly endDate, TimeOnly? reminderTime, IReadOnlyList<ExercisePlanItemInput> items, CancellationToken ct);
    Task<IReadOnlyList<ExercisePlanSummaryDto>> ListAsync(Guid userId, CancellationToken ct);
    Task<ExercisePlanDto?> GetByIdAsync(Guid userId, Guid planId, CancellationToken ct);
    Task<bool> DeleteAsync(Guid userId, Guid planId, CancellationToken ct);
    Task<bool?> ToggleCheckInAsync(Guid userId, Guid itemId, CancellationToken ct);
    Task<bool> CheckInAsync(Guid userId, Guid itemId, CancellationToken ct);
    Task<ExercisePlanDto?> GetLatestAsync(Guid userId, CancellationToken ct);
}

public interface IExerciseRepository
{
    Task<IReadOnlyList<ExercisePlan>> ListActiveOnAsync(Guid userId, DateOnly date, CancellationToken ct);
    Task<IReadOnlyList<ExercisePlan>> ListAsync(Guid userId, int limit, CancellationToken ct);
    Task<ExercisePlan?> GetOwnedPlanAsync(Guid userId, Guid planId, CancellationToken ct);
    Task<ExercisePlan?> GetLatestAsync(Guid userId, CancellationToken ct);
    Task<ExercisePlanItem?> GetOwnedItemAsync(Guid userId, Guid itemId, CancellationToken ct);
    Task AddAsync(ExercisePlan plan, CancellationToken ct);
    void Delete(ExercisePlan plan);
    Task SaveChangesAsync(CancellationToken ct);
}

public interface IExerciseReminderProducer
{
    Task<int> ProduceDueAsync(DateTime utcNow, CancellationToken ct);
}
