using Health.Domain.Enums;
using Health.Domain.Entities;

namespace Health.Application.HealthRecords;

public sealed record HealthRecordUpsertRequest(
    HealthMetricType Type,
    int? Systolic,
    int? Diastolic,
    decimal? Value,
    string? Unit,
    HealthRecordSource Source,
    DateTime? RecordedAt);

public sealed record HealthRecordDto(
    Guid Id,
    string Type,
    int? Systolic,
    int? Diastolic,
    decimal? Value,
    string? Unit,
    string Source,
    bool IsAbnormal,
    DateTime RecordedAt);

public interface IHealthRecordService
{
    Task<IReadOnlyList<HealthRecordDto>> GetRecordsAsync(Guid userId, string? type, int? days, CancellationToken ct);
    Task<Guid> CreateAsync(Guid userId, HealthRecordUpsertRequest request, CancellationToken ct);
    Task<IReadOnlyList<Guid>> CreateManyAsync(Guid userId, IReadOnlyList<HealthRecordUpsertRequest> requests, CancellationToken ct);
    Task<bool> UpdateAsync(Guid userId, Guid id, HealthRecordUpsertRequest request, CancellationToken ct);
    Task<bool> DeleteAsync(Guid userId, Guid id, CancellationToken ct);
    Task<Dictionary<string, object?>> GetLatestAsync(Guid userId, CancellationToken ct);
    Task<IReadOnlyList<object>> GetTrendAsync(Guid userId, HealthMetricType type, int period, CancellationToken ct);
}

public interface IHealthRecordRepository
{
    Task<IReadOnlyList<HealthRecord>> ListAsync(Guid userId, HealthMetricType? type, DateTime? recordedAfter, int limit, CancellationToken ct);
    Task<HealthRecord?> GetOwnedAsync(Guid userId, Guid id, CancellationToken ct);
    Task<HealthRecord?> GetLatestByTypeAsync(Guid userId, HealthMetricType type, CancellationToken ct);
    Task<IReadOnlyList<HealthRecord>> GetTrendAsync(Guid userId, HealthMetricType type, DateTime recordedAfter, CancellationToken ct);
    Task AddAsync(HealthRecord record, CancellationToken ct);
    void Delete(HealthRecord record);
    Task SaveChangesAsync(CancellationToken ct);
}
