using Health.Application.Exercises;

namespace Health.Infrastructure.AI.AgentHandlers;

public static class ExerciseAgentHandler
{
    public static readonly ToolDefinition ManageExerciseTool = new()
    {
        Function = new()
        {
            Name = "manage_exercise",
            Description = "运动计划管理（创建/查询/打卡）",
            Parameters = new
            {
                type = "object",
                properties = new
                {
                    action = new { type = "string", description = "create/query/checkin" },
                    start_date = new { type = "string", description = "开始日期 yyyy-MM-dd，默认今天" },
                    duration_days = new { type = "integer", description = "连续运动天数，如一周为7天" },
                    exercise_type = new { type = "string", description = "运动类型，如散步、慢跑、游泳" },
                    duration_minutes = new { type = "integer", description = "每天运动时长，单位分钟" },
                    reminder_time = new { type = "string", description = "每天提醒时间 HH:mm，默认19:00" },
                    item_id = new { type = "string", description = "打卡条目 ID" },
                },
                required = new[] { "action" },
            },
        },
    };

    public static List<ToolDefinition> Tools => [ManageExerciseTool];

    public static async Task<object> Execute(
        string toolName,
        JsonElement args,
        AppDbContext db,
        Guid userId,
        IExerciseService? exercises = null,
        CancellationToken ct = default)
    {
        if (toolName != "manage_exercise" || exercises == null)
            return new { success = false, message = $"未知工具: {toolName}" };

        var action = args.TryGetProperty("action", out var actionValue) ? actionValue.GetString() : "query";
        if (action == "create")
        {
            var startDate = args.TryGetProperty("start_date", out var startValue) && DateOnly.TryParse(startValue.GetString(), out var parsedStart)
                ? parsedStart
                : DateOnly.FromDateTime(DateTime.UtcNow.AddHours(8));
            var days = args.TryGetProperty("duration_days", out var daysValue) && daysValue.TryGetInt32(out var parsedDays)
                ? Math.Clamp(parsedDays, 1, 366)
                : 7;
            var exerciseType = args.TryGetProperty("exercise_type", out var typeValue) ? typeValue.GetString() : "散步";
            var minutes = args.TryGetProperty("duration_minutes", out var minutesValue) && minutesValue.TryGetInt32(out var parsedMinutes) ? parsedMinutes : 30;
            var reminder = args.TryGetProperty("reminder_time", out var reminderValue) && TimeOnly.TryParse(reminderValue.GetString(), out var parsedReminder)
                ? parsedReminder
                : new TimeOnly(19, 0);
            var planId = await exercises.CreateAsync(userId, new ExercisePlanCreateRequest(
                startDate, startDate.AddDays(days - 1), exerciseType, minutes, reminder), ct);
            return new { success = true, plan_id = planId, exercise_type = exerciseType, duration_minutes = minutes, day_count = days, start_date = startDate, end_date = startDate.AddDays(days - 1), reminder_time = reminder };
        }

        if (action == "checkin")
        {
            var itemId = args.TryGetProperty("item_id", out var itemValue) && itemValue.TryGetGuid(out var parsedId) ? parsedId : Guid.Empty;
            var success = await exercises.CheckInAsync(userId, itemId, ct);
            return success ? new { success = true } : new { success = false, message = "条目不存在" };
        }

        var plan = await exercises.GetLatestAsync(userId, ct);
        return plan == null
            ? new { found = false }
            : new
            {
                found = true,
                plan_id = plan.Id,
                plan.StartDate,
                plan.EndDate,
                plan.ReminderTime,
                items = plan.Items.Select(i => new { i.Id, i.ScheduledDate, i.ExerciseType, i.DurationMinutes, i.IsCompleted }),
            };
    }
}
