using Health.Application.HealthRecords;

namespace Health.WebApi.Endpoints;

/// <summary>
/// 健康数据 API 端点
/// </summary>
public static class HealthEndpoints
{
    public static void MapHealthEndpoints(this WebApplication app)
    {
        var group = app.MapGroup("/api/health-records").RequireAuthorization();

        group.MapGet("/", async (
            string? type,
            int? days,
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var records = await healthRecords.GetRecordsAsync(userId, type, days, ct);
            return Results.Ok(new { code = 0, data = records, message = (string?)null });
        });

        group.MapPost("/", async (
            CreateHealthRecordRequest req,
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var id = await healthRecords.CreateAsync(userId, req.ToServiceRequest(), ct);
            return Results.Ok(new { code = 0, data = new { id }, message = (string?)null });
        });

        group.MapPut("/{id:guid}", async (
            Guid id,
            CreateHealthRecordRequest req,
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var ok = await healthRecords.UpdateAsync(userId, id, req.ToServiceRequest(), ct);
            return ok
                ? Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null })
                : Results.Ok(new { code = 40004, data = (object?)null, message = "记录不存在" });
        });

        group.MapDelete("/{id:guid}", async (
            Guid id,
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var ok = await healthRecords.DeleteAsync(userId, id, ct);
            return ok
                ? Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null })
                : Results.Ok(new { code = 40004, data = (object?)null, message = "记录不存在" });
        });

        group.MapGet("/latest", async (
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var latest = await healthRecords.GetLatestAsync(userId, ct);
            return Results.Ok(new { code = 0, data = latest, message = (string?)null });
        });

        group.MapGet("/trend", async (
            string type,
            int period,
            HttpContext http,
            IHealthRecordService healthRecords,
            CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            if (!Enum.TryParse<HealthMetricType>(type, ignoreCase: true, out var metricType))
                return Results.Ok(new { code = 40001, data = (object?)null, message = "不支持的指标类型" });

            var records = await healthRecords.GetTrendAsync(userId, metricType, period, ct);
            return Results.Ok(new { code = 0, data = records, message = (string?)null });
        });
    }

    private static Guid GetUserId(HttpContext http) =>
        Guid.TryParse(http.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;
}

public sealed class CreateHealthRecordRequest
{
    public HealthMetricType Type { get; init; }
    public int? Systolic { get; init; }
    public int? Diastolic { get; init; }
    public decimal? Value { get; init; }
    public string? Unit { get; init; }
    public HealthRecordSource Source { get; init; }
    public DateTime? RecordedAt { get; init; }

    public HealthRecordUpsertRequest ToServiceRequest() => new(
        Type,
        Systolic,
        Diastolic,
        Value,
        Unit,
        Source,
        RecordedAt);
}
