using Health.Application.HealthRecords;

namespace Health.Infrastructure.AI.AgentHandlers;

/// <summary>
/// 记数据 Agent 工具处理器——录入健康指标
/// </summary>
public static class HealthDataAgentHandler
{
    public static readonly ToolDefinition RecordHealthDataTool = new()
    {
        Function = new()
        {
            Name = "record_health_data", Description = "记录健康数据（血压/心率/血糖/血氧/体重）",
            Parameters = new { type = "object", properties = new { type = new { type = "string" }, systolic = new { type = "integer" }, diastolic = new { type = "integer" }, heart_rate = new { type = "number" }, glucose = new { type = "number" }, spo2 = new { type = "number" }, weight = new { type = "number" } }, required = new[] { "type" } }
        }
    };

    public static List<ToolDefinition> Tools => [RecordHealthDataTool, CommonAgentHandler.QueryHealthRecordsTool];

    public static async Task<object> Execute(string toolName, JsonElement args, Guid userId, IHealthRecordService healthRecords)
    {
        return toolName switch
        {
            "record_health_data" => await ExecuteRecordHealthData(healthRecords, userId, args),
            _ => new { success = false, message = $"未知工具: {toolName}" }
        };
    }

    private static async Task<object> ExecuteRecordHealthData(IHealthRecordService healthRecords, Guid userId, JsonElement args)
    {
        var type = args.TryGetProperty("type", out var t) ? t.GetString()! : "";
        var (metricType, value, unit, systolic, diastolic) = ParseMetric(type, args);
        if (metricType == null)
            return new { success = false, message = $"未知指标类型: {type}" };

        var recordedAt = args.TryGetProperty("recorded_at", out var ra) && ra.TryGetDateTime(out var dt)
            ? dt
            : DateTime.UtcNow;

        var request = new HealthRecordUpsertRequest(
            metricType.Value,
            systolic,
            diastolic,
            value,
            unit,
            HealthRecordSource.AiEntry,
            recordedAt);

        var id = await healthRecords.CreateAsync(userId, request, CancellationToken.None);
        var valStr = metricType == HealthMetricType.BloodPressure ? $"{systolic}/{diastolic}" : value?.ToString() ?? "";
        return new
        {
            success = true,
            record_id = id,
            type = metricType.Value.ToString(),
            value = valStr,
            unit,
            isAbnormal = HealthRecordRules.CheckAbnormal(request)
        };
    }

    private static (HealthMetricType? Type, decimal? Value, string Unit, int? Systolic, int? Diastolic) ParseMetric(string type, JsonElement args)
    {
        return type switch
        {
            "blood_pressure" => (
                HealthMetricType.BloodPressure,
                null,
                "mmHg",
                args.TryGetProperty("systolic", out var s) ? s.GetInt32() : null,
                args.TryGetProperty("diastolic", out var d) ? d.GetInt32() : null),
            "heart_rate" => (
                HealthMetricType.HeartRate,
                args.TryGetProperty("heart_rate", out var hr) ? hr.GetDecimal() : null,
                "次/分",
                null,
                null),
            "glucose" => (
                HealthMetricType.Glucose,
                args.TryGetProperty("glucose", out var g) ? g.GetDecimal() : null,
                "mmol/L",
                null,
                null),
            "spo2" => (
                HealthMetricType.SpO2,
                args.TryGetProperty("spo2", out var o) ? o.GetDecimal() : null,
                "%",
                null,
                null),
            "weight" => (
                HealthMetricType.Weight,
                args.TryGetProperty("weight", out var w) ? w.GetDecimal() : null,
                "kg",
                null,
                null),
            _ => (null, null, "", null, null)
        };
    }
}
