using System.Security.Claims;
using Health.Domain.Entities;
using Health.Domain.Enums;
using Microsoft.EntityFrameworkCore;

namespace Health.WebApi.Endpoints;

/// <summary>
/// 医生端 API（需JWT鉴权 + Role=Doctor）
/// </summary>
public static class DoctorEndpoints
{
    private static Guid GetUserId(HttpContext http) =>
        Guid.TryParse(http.User.FindFirst(ClaimTypes.NameIdentifier)?.Value, out var id) ? id : Guid.Empty;

    private static string GetUserRole(HttpContext http) =>
        http.User.FindFirst("Role")?.Value ?? http.User.FindFirst(ClaimTypes.Role)?.Value ?? "User";

    private static async Task<DoctorProfile?> GetDoctorProfile(HttpContext http, AppDbContext db)
    {
        var userId = GetUserId(http);
        if (userId == Guid.Empty) return null;
        return await db.DoctorProfiles.FirstOrDefaultAsync(d => d.UserId == userId);
    }

    private static async Task<Guid?> GetDoctorEntityId(HttpContext http, AppDbContext db)
    {
        var profile = await GetDoctorProfile(http, db);
        return profile?.DoctorId;
    }

    public static (DateTime StartUtc, DateTime EndUtc) GetBeijingDayRange(DateTime utcNow)
    {
        var beijingNow = utcNow.ToUniversalTime().AddHours(8);
        var startUtc = new DateTime(
            beijingNow.Year,
            beijingNow.Month,
            beijingNow.Day,
            0,
            0,
            0,
            DateTimeKind.Utc).AddHours(-8);
        return (startUtc, startUtc.AddDays(1));
    }

    public static void MapDoctorEndpoints(this WebApplication app)
    {
        var group = app.MapGroup("/api/doctor").RequireAuthorization();

        // 中间件：校验医生身份
        group.AddEndpointFilter(async (context, next) =>
        {
            var http = context.HttpContext;
            var role = GetUserRole(http);
            if (role != "Doctor")
                return Results.Json(new { code = 403, data = (object?)null, message = "仅医生可访问" }, statusCode: 403);
            return await next(context);
        });

        // ===== 工作台 =====
        group.MapGet("/dashboard", async (HttpContext http, AppDbContext db) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null)
                return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在，请先完善个人信息" });
            if (profile.DoctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var doctorId = profile.DoctorId.Value;
            var totalPatients = await db.Users.CountAsync(u => u.Role == "User" && u.DoctorId == doctorId);
            var activeConsultations = await db.Consultations.CountAsync(c => c.User.DoctorId == doctorId && c.Status != ConsultationStatus.Closed);
            var pendingReports = await db.Reports.CountAsync(r => r.User.DoctorId == doctorId && r.Status == ReportStatus.PendingDoctor);
            var (todayStart, todayEnd) = GetBeijingDayRange(DateTime.UtcNow);
            var todayFollowUps = await db.FollowUps.CountAsync(f => f.User.DoctorId == doctorId && f.ScheduledAt >= todayStart && f.ScheduledAt < todayEnd && f.Status == FollowUpStatus.Upcoming);

            // 待办列表
            var pendingConsultations = await db.Consultations
                .Where(c => c.User.DoctorId == doctorId && c.Status == ConsultationStatus.WaitingDoctor)
                .OrderByDescending(c => c.CreatedAt)
                .Take(5)
                .Select(c => new { c.Id, PatientName = c.User.Name ?? c.User.Phone, c.CreatedAt })
                .ToListAsync();

            var pendingReportList = await db.Reports
                .Where(r => r.User.DoctorId == doctorId && r.Status == ReportStatus.PendingDoctor)
                .OrderByDescending(r => r.CreatedAt)
                .Take(5)
                .Select(r => new { r.Id, PatientName = r.User.Name ?? r.User.Phone, r.Category, r.CreatedAt })
                .ToListAsync();

            var todayFollowUpList = await db.FollowUps
                .Where(f => f.User.DoctorId == doctorId && f.ScheduledAt >= todayStart && f.ScheduledAt < todayEnd && f.Status == FollowUpStatus.Upcoming)
                .OrderBy(f => f.ScheduledAt)
                .Select(f => new { f.Id, f.Title, PatientName = f.User.Name ?? f.User.Phone, f.ScheduledAt })
                .ToListAsync();

            return Results.Ok(new
            {
                code = 0,
                data = new
                {
                    doctorName = profile.Name,
                    doctorTitle = profile.Title,
                    doctorDepartment = profile.Department,
                    doctorHospital = profile.Hospital,
                    doctorAvatar = profile.AvatarUrl,
                    doctorOnline = profile.IsOnline,
                    doctorActive = profile.IsActive,
                    stats = new { totalPatients, activeConsultations, pendingReports, todayFollowUps },
                    pendingConsultations,
                    pendingReports = pendingReportList,
                    todayFollowUps = todayFollowUpList
                },
                message = (string?)null
            });
        });

        // ===== 患者列表 =====
        group.MapGet("/patients", async (HttpContext http, AppDbContext db, string? search, int page = 1, int pageSize = 20) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });
            var query = db.Users.Where(u => u.Role == "User" && u.DoctorId == doctorId).AsQueryable();
            if (!string.IsNullOrWhiteSpace(search))
            {
                query = query.Where(u =>
                    (u.Name != null && u.Name.Contains(search)) ||
                    (u.Phone != null && u.Phone.Contains(search)));
            }
            var total = await query.CountAsync();
            var patients = await query.OrderByDescending(u => u.CreatedAt)
                .Skip((page - 1) * pageSize).Take(pageSize)
                .Select(u => new { u.Id, u.Phone, u.Name, u.Gender, u.BirthDate, hasArchive = u.HealthArchive != null })
                .ToListAsync();

            return Results.Ok(new { code = 0, data = new { total, page, pageSize, items = patients }, message = (string?)null });
        });

        // ===== 患者详情 =====
        group.MapGet("/patients/{id:guid}", async (Guid id, HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var user = await db.Users
                .Include(u => u.HealthArchive)
                .ThenInclude(a => a!.Surgeries)
                .FirstOrDefaultAsync(u => u.Id == id && u.DoctorId == doctorId);
            if (user == null)
                return Results.Ok(new { code = 404, data = (object?)null, message = "患者不存在" });

            var latestRecords = await db.HealthRecords
                .Where(r => r.UserId == id)
                .GroupBy(r => r.MetricType)
                .Select(g => g.OrderByDescending(r => r.RecordedAt).First())
                .ToListAsync();

            var thirtyDaysAgo = DateTime.UtcNow.AddDays(-30);
            var trendRecords = await db.HealthRecords
                .Where(r => r.UserId == id && r.RecordedAt >= thirtyDaysAgo)
                .OrderBy(r => r.RecordedAt)
                .Select(r => new { r.Id, MetricType = r.MetricType.ToString(), r.Systolic, r.Diastolic, r.Value, r.Unit, r.RecordedAt, r.IsAbnormal })
                .ToListAsync();

            var medications = await db.Medications
                .Where(m => m.UserId == id && m.IsActive)
                .OrderByDescending(m => m.StartDate)
                .Select(m => new { m.Id, m.Name, m.Dosage, Frequency = m.Frequency.ToString(), m.TimeOfDay, m.StartDate, m.EndDate })
                .ToListAsync();

            var dietRecords = await db.DietRecords
                .Where(d => d.UserId == id).OrderByDescending(d => d.RecordedAt).Take(7).Include(d => d.FoodItems)
                .ToListAsync();

            var exercisePlans = await db.ExercisePlans
                .Where(p => p.UserId == id).OrderByDescending(p => p.StartDate).Take(1).Include(p => p.Items)
                .FirstOrDefaultAsync();

            var reports = await db.Reports
                .Where(r => r.UserId == id).OrderByDescending(r => r.CreatedAt)
                .Select(r => new { r.Id, r.FileUrl, FileType = r.FileType.ToString(), Category = r.Category.ToString(), Status = r.Status.ToString(), r.Severity, r.AiSummary, r.AiIndicators, r.DoctorComment, r.DoctorRecommendation, r.DoctorName, r.ReviewedAt, r.CreatedAt })
                .ToListAsync();

            var followUps = await db.FollowUps
                .Where(f => f.UserId == id).OrderByDescending(f => f.ScheduledAt)
                .Select(f => new { f.Id, f.Title, f.DoctorName, f.Department, f.ScheduledAt, f.Notes, Status = f.Status.ToString(), f.CreatedAt })
                .ToListAsync();

            return Results.Ok(new
            {
                code = 0,
                data = new
                {
                    profile = new { user.Id, user.Phone, user.Name, user.Gender, BirthDate = user.BirthDate?.ToString("yyyy-MM-dd"), user.AvatarUrl },
                    archive = user.HealthArchive == null ? null : new
                    {
                        user.HealthArchive.Diagnosis,
                        user.HealthArchive.SurgeryType,
                        SurgeryDate = user.HealthArchive.SurgeryDate?.ToString("yyyy-MM-dd"),
                        surgeries = user.HealthArchive.Surgeries.OrderBy(s => s.SortOrder)
                            .Select(s => new { s.Type, Date = s.Date.HasValue ? s.Date.Value.ToString("yyyy-MM-dd") : null }),
                        user.HealthArchive.Allergies,
                        user.HealthArchive.DietRestrictions,
                        user.HealthArchive.ChronicDiseases,
                        user.HealthArchive.FamilyHistory,
                        user.HealthArchive.SurgeryHistoryStatus
                    },
                    latestRecords,
                    trendRecords,
                    medications,
                    dietRecords = dietRecords.Select(d => new { d.Id, MealType = d.MealType.ToString(), d.TotalCalories, d.HealthScore, d.RecordedAt, foods = d.FoodItems.Select(f => new { f.Name, f.Portion, f.Calories, f.Warning }) }),
                    exercisePlan = exercisePlans == null ? null : new { exercisePlans.StartDate, exercisePlans.EndDate, exercisePlans.ReminderTime, items = exercisePlans.Items.Select(i => new { i.ScheduledDate, i.ExerciseType, i.DurationMinutes, i.IsCompleted, i.IsRestDay, i.CompletedAt }) },
                    reports, followUps
                },
                message = (string?)null
            });
        });

        // ===== 问诊列表 =====
        group.MapGet("/consultations", async (HttpContext http, AppDbContext db) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });
            if (profile.DoctorId == null) return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var consultations = await db.Consultations
                .Where(c => c.User.DoctorId == profile.DoctorId)
                .OrderByDescending(c => c.CreatedAt)
                .Select(c => new { c.Id, c.UserId, PatientName = c.User.Name, PatientPhone = c.User.Phone, Status = c.Status.ToString(), c.CreatedAt, c.ClosedAt, LastMessage = c.Messages.OrderByDescending(m => m.CreatedAt).Select(m => new { m.Content, SenderType = m.SenderType.ToString(), m.CreatedAt }).FirstOrDefault() })
                .ToListAsync();

            return Results.Ok(new { code = 0, data = consultations, message = (string?)null });
        });

        // ===== 问诊消息 =====
        group.MapGet("/consultations/{id:guid}/messages", async (Guid id, HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var consultation = await db.Consultations
                .FirstOrDefaultAsync(c => c.Id == id && c.User.DoctorId == doctorId);
            if (consultation == null)
                return Results.Ok(new { code = 404, data = (object?)null, message = "问诊不存在" });

            var messages = await db.ConsultationMessages
                .Where(m => m.ConsultationId == consultation.Id).OrderBy(m => m.CreatedAt)
                .Select(m => new { m.Id, SenderType = m.SenderType.ToString(), m.SenderName, m.Content, m.CreatedAt })
                .ToListAsync();

            return Results.Ok(new { code = 0, data = new { status = consultation?.Status.ToString() ?? "Closed", messages }, message = (string?)null });
        });

        // ===== 医生发送消息 =====
        group.MapPost("/consultations/{id:guid}/messages", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });
            if (profile.DoctorId == null) return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var consultation = await db.Consultations.FirstOrDefaultAsync(c => c.Id == id && c.User.DoctorId == profile.DoctorId, ct);
            if (consultation == null) return Results.Ok(new { code = 404, data = (object?)null, message = "问诊不存在" });

            using var reader = new StreamReader(http.Request.Body);
            var body = await reader.ReadToEndAsync(ct);
            var json = System.Text.Json.JsonDocument.Parse(body);
            var content = json.RootElement.GetProperty("content").GetString() ?? "";

            var msg = new ConsultationMessage
            {
                Id = Guid.NewGuid(), ConsultationId = id,
                SenderType = ConsultationSenderType.Doctor,
                SenderName = $"医生 · {profile.Name}",
                Content = content, CreatedAt = DateTime.UtcNow
            };
            db.ConsultationMessages.Add(msg);

            if (consultation.Status == ConsultationStatus.AiTalking || consultation.Status == ConsultationStatus.WaitingDoctor)
                consultation.Status = ConsultationStatus.DoctorReplied;

            await db.SaveChangesAsync(ct);

            var hubContext = http.RequestServices.GetService<Microsoft.AspNetCore.SignalR.IHubContext<Hubs.ConsultationHub>>();
            if (hubContext != null)
            {
                await hubContext.Clients.Group(id.ToString()).SendAsync("ReceiveMessage", new { msg.Id, consultationId = id.ToString(), senderType = "Doctor", senderName = msg.SenderName, content, msg.CreatedAt });
            }

            return Results.Ok(new { code = 0, data = new { msg.Id }, message = (string?)null });
        });

        // ===== 报告列表 =====
        group.MapGet("/reports", async (string? status, HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var query = db.Reports.Where(r => r.User.DoctorId == doctorId);
            if (!string.IsNullOrWhiteSpace(status) && Enum.TryParse<ReportStatus>(status, out var s))
                query = query.Where(r => r.Status == s);

            var reports = await query.OrderByDescending(r => r.CreatedAt)
                .Select(r => new { r.Id, r.UserId, PatientName = r.User.Name, r.FileUrl, FileType = r.FileType.ToString(), Category = r.Category.ToString(), Status = r.Status.ToString(), r.Severity, r.AiSummary, r.AiIndicators, r.DoctorComment, r.DoctorRecommendation, r.DoctorName, r.ReviewedAt, r.CreatedAt })
                .ToListAsync();
            return Results.Ok(new { code = 0, data = reports, message = (string?)null });
        });

        // ===== 报告详情 =====
        group.MapGet("/reports/{id:guid}", async (Guid id, HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var report = await db.Reports.Where(r => r.Id == id && r.User.DoctorId == doctorId)
                .Select(r => new { r.Id, r.UserId, PatientName = r.User.Name, r.FileUrl, FileType = r.FileType.ToString(), Category = r.Category.ToString(), Status = r.Status.ToString(), r.Severity, r.AiSummary, r.AiIndicators, r.DoctorComment, r.DoctorRecommendation, r.DoctorName, r.ReviewedAt, r.CreatedAt })
                .FirstOrDefaultAsync();
            if (report == null) return Results.Ok(new { code = 404, data = (object?)null, message = "报告不存在" });
            return Results.Ok(new { code = 0, data = report, message = (string?)null });
        });

        // ===== 审阅报告 =====
        group.MapPost("/reports/{id:guid}/review", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });
            if (profile.DoctorId == null) return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var report = await db.Reports.FirstOrDefaultAsync(r => r.Id == id && r.User.DoctorId == profile.DoctorId, ct);
            if (report == null) return Results.Ok(new { code = 404, data = (object?)null, message = "报告不存在" });

            using var reader = new StreamReader(http.Request.Body);
            var body = await reader.ReadToEndAsync(ct);
            var json = JsonDocument.Parse(body);

            report.Severity = json.RootElement.TryGetProperty("severity", out var sv) ? sv.GetString() : null;
            report.DoctorComment = json.RootElement.TryGetProperty("comment", out var cm) ? cm.GetString() : null;
            report.DoctorRecommendation = json.RootElement.TryGetProperty("recommendation", out var rc) ? rc.GetString() : null;
            report.DoctorName = profile.Name;
            report.ReviewedAt = DateTime.UtcNow;
            report.Status = ReportStatus.DoctorReviewed;

            if (json.RootElement.TryGetProperty("indicators", out var inds))
                report.AiIndicators = inds.GetRawText();

            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
        });

        // ===== 随访列表 =====
        group.MapGet("/follow-ups", async (string? status, string? patientId, HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var query = db.FollowUps.Where(f => f.User.DoctorId == doctorId);
            if (!string.IsNullOrWhiteSpace(status) && Enum.TryParse<FollowUpStatus>(status, out var s))
                query = query.Where(f => f.Status == s);
            if (Guid.TryParse(patientId, out var pid))
                query = query.Where(f => f.UserId == pid);

            var followUps = await query.OrderByDescending(f => f.ScheduledAt)
                .Select(f => new { f.Id, f.UserId, PatientName = f.User.Name, f.Title, f.DoctorName, f.Department, f.ScheduledAt, f.Notes, Status = f.Status.ToString(), f.CreatedAt })
                .ToListAsync();
            return Results.Ok(new { code = 0, data = followUps, message = (string?)null });
        });

        // ===== 创建随访 =====
        group.MapPost("/follow-ups", async (HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });
            if (profile.DoctorId == null) return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            using var reader = new StreamReader(http.Request.Body);
            var body = await reader.ReadToEndAsync(ct);
            var json = System.Text.Json.JsonDocument.Parse(body);
            var patientId = Guid.Parse(json.RootElement.GetProperty("userId").GetString()!);
            var patientExists = await db.Users.AnyAsync(u => u.Id == patientId && u.DoctorId == profile.DoctorId, ct);
            if (!patientExists) return Results.Ok(new { code = 404, data = (object?)null, message = "患者不存在" });

            var followUp = new FollowUp
            {
                Id = Guid.NewGuid(),
                UserId = patientId,
                Title = json.RootElement.GetProperty("title").GetString() ?? "",
                DoctorName = profile.Name,
                Department = profile.Department,
                ScheduledAt = DateTime.Parse(json.RootElement.GetProperty("scheduledAt").GetString()!),
                Notes = json.RootElement.TryGetProperty("notes", out var n) ? n.GetString() : null,
                Status = FollowUpStatus.Upcoming,
                CreatedAt = DateTime.UtcNow
            };
            db.FollowUps.Add(followUp);
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { followUp.Id }, message = (string?)null });
        });

        // ===== 更新随访 =====
        group.MapPut("/follow-ups/{id:guid}", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var followUp = await db.FollowUps.FirstOrDefaultAsync(f => f.Id == id && f.User.DoctorId == doctorId, ct);
            if (followUp == null) return Results.Ok(new { code = 404, data = (object?)null, message = "随访不存在" });

            using var reader = new StreamReader(http.Request.Body);
            var body = await reader.ReadToEndAsync(ct);
            var json = System.Text.Json.JsonDocument.Parse(body);
            if (json.RootElement.TryGetProperty("title", out var t)) followUp.Title = t.GetString() ?? followUp.Title;
            if (json.RootElement.TryGetProperty("scheduledAt", out var sa)) followUp.ScheduledAt = DateTime.Parse(sa.GetString()!);
            if (json.RootElement.TryGetProperty("notes", out var no)) followUp.Notes = no.GetString();
            if (json.RootElement.TryGetProperty("status", out var st) && Enum.TryParse<FollowUpStatus>(st.GetString(), out var fs)) followUp.Status = fs;
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
        });

        // ===== 删除随访 =====
        group.MapDelete("/follow-ups/{id:guid}", async (Guid id, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });

            var followUp = await db.FollowUps.FirstOrDefaultAsync(f => f.Id == id && f.User.DoctorId == doctorId, ct);
            if (followUp == null) return Results.Ok(new { code = 404, data = (object?)null, message = "随访不存在" });
            db.FollowUps.Remove(followUp);
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
        });

        // ===== 患者列表（简版）=====
        group.MapGet("/patients-simple", async (HttpContext http, AppDbContext db) =>
        {
            var doctorId = await GetDoctorEntityId(http, db);
            if (doctorId == null)
                return Results.Ok(new { code = 500, data = (object?)null, message = "医生档案未关联" });
            var query = db.Users.Where(u => u.Role == "User" && u.DoctorId == doctorId);
            var patients = await query.OrderBy(u => u.Name).Select(u => new { u.Id, u.Name, u.Phone }).ToListAsync();
            return Results.Ok(new { code = 0, data = patients, message = (string?)null });
        });

        // ===== 医生个人信息 =====
        group.MapGet("/profile", async (HttpContext http, AppDbContext db) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });
            return Results.Ok(new { code = 0, data = new { profile.Id, profile.Name, profile.Title, profile.Department, profile.Hospital, profile.AvatarUrl, profile.IsOnline }, message = (string?)null });
        });

        // ===== 更新医生个人信息 =====
        group.MapPut("/profile", async (HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var profile = await GetDoctorProfile(http, db);
            if (profile == null) return Results.Ok(new { code = 404, data = (object?)null, message = "医生档案不存在" });

            using var reader = new StreamReader(http.Request.Body);
            var body = await reader.ReadToEndAsync(ct);
            var json = JsonDocument.Parse(body);
            if (json.RootElement.TryGetProperty("name", out var n)) profile.Name = n.GetString();
            if (json.RootElement.TryGetProperty("title", out var t)) profile.Title = t.GetString();
            if (json.RootElement.TryGetProperty("department", out var d)) profile.Department = d.GetString();
            if (json.RootElement.TryGetProperty("hospital", out var h)) profile.Hospital = h.GetString();
            if (json.RootElement.TryGetProperty("avatarUrl", out var a)) profile.AvatarUrl = a.GetString();
            if (json.RootElement.TryGetProperty("isOnline", out var o)) profile.IsOnline = o.GetBoolean();
            profile.UpdatedAt = DateTime.UtcNow;
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { success = true }, message = (string?)null });
        });
    }
}
