using Health.Application.Medications;
using Health.Domain.Entities;

namespace Health.Tests;

public sealed class MedicationUpdateTests
{
    [Fact]
    public async Task Update_CanClearAnExistingEndDate()
    {
        var medication = new Medication
        {
            Id = Guid.NewGuid(),
            UserId = Guid.NewGuid(),
            Name = "阿司匹林",
            StartDate = new DateOnly(2026, 7, 1),
            EndDate = new DateOnly(2026, 7, 31),
        };
        var repository = new FakeMedicationRepository(medication);
        var service = new MedicationService(repository);

        var updated = await service.UpdateAsync(
            medication.UserId,
            medication.Id,
            new MedicationPatchRequest(
                null, null, null, null, null, null, null,
                ClearEndDate: true),
            CancellationToken.None);

        Assert.True(updated);
        Assert.Null(medication.EndDate);
        Assert.True(repository.Saved);
    }

    private sealed class FakeMedicationRepository(Medication medication) : IMedicationRepository
    {
        public bool Saved { get; private set; }

        public Task<IReadOnlyList<Medication>> ListAsync(Guid userId, string? filter, CancellationToken ct) => Task.FromResult<IReadOnlyList<Medication>>([medication]);
        public Task<IReadOnlyList<Medication>> ListActiveForRemindersAsync(Guid userId, DateOnly today, CancellationToken ct) => Task.FromResult<IReadOnlyList<Medication>>([medication]);
        public Task<IReadOnlyList<MedicationLog>> ListLogsInWindowAsync(Guid userId, DateTime startUtc, DateTime endUtc, CancellationToken ct) => Task.FromResult<IReadOnlyList<MedicationLog>>([]);
        public Task<Medication?> GetOwnedAsync(Guid userId, Guid medicationId, CancellationToken ct) => Task.FromResult<Medication?>(medication.UserId == userId && medication.Id == medicationId ? medication : null);
        public Task<bool> ExistsOwnedAsync(Guid userId, Guid medicationId, CancellationToken ct) => Task.FromResult(medication.UserId == userId && medication.Id == medicationId);
        public Task<MedicationLog?> GetTodayTakenLogAsync(Guid userId, Guid medicationId, DateTime startUtc, DateTime endUtc, CancellationToken ct) => Task.FromResult<MedicationLog?>(null);
        public Task<bool> DoseLogExistsAsync(Guid userId, Guid medicationId, TimeOnly scheduledTime, DateTime startUtc, DateTime endUtc, CancellationToken ct) => Task.FromResult(false);
        public Task<MedicationLog?> GetDoseLogAsync(Guid userId, Guid medicationId, TimeOnly scheduledTime, DateTime startUtc, DateTime endUtc, CancellationToken ct) => Task.FromResult<MedicationLog?>(null);
        public Task<IReadOnlyList<Medication>> ListActiveForReminderScanAsync(CancellationToken ct) => Task.FromResult<IReadOnlyList<Medication>>([medication]);
        public Task AddMedicationAsync(Medication value, CancellationToken ct) => Task.CompletedTask;
        public Task AddLogAsync(MedicationLog log, CancellationToken ct) => Task.CompletedTask;
        public void DeleteMedication(Medication value) { }
        public void DeleteLog(MedicationLog log) { }
        public Task SaveChangesAsync(CancellationToken ct) { Saved = true; return Task.CompletedTask; }
    }
}
