namespace Health.WebApi.Endpoints;

public static class ConsultationEndpoints
{
    public static void MapConsultationEndpoints(this WebApplication app)
    {
        var group = app.MapGroup("/api").RequireAuthorization();

        group.MapGet("/doctors", async (AppDbContext db) =>
        {
            var doctors = await db.Doctors.Where(d => d.IsActive).Select(d => new { d.Id, d.Name, d.Title, d.Department, d.Introduction }).ToListAsync();
            return Results.Ok(new { code = 0, data = doctors, message = (string?)null });
        });

        group.MapGet("/consultations", async (HttpContext http, AppDbContext db) =>
        {
            var userId = GetUserId(http);
            var consultations = await db.Consultations.Where(c => c.UserId == userId).OrderByDescending(c => c.CreatedAt).ToListAsync();
            return Results.Ok(new { code = 0, data = consultations, message = (string?)null });
        });

        group.MapPost("/consultations", async (CreateConsultationRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var consultation = new Consultation
            {
                Id = Guid.NewGuid(), UserId = userId, DoctorId = req.DoctorId,
                Status = ConsultationStatus.AiTalking,
                Month = DateTime.UtcNow.Year * 100 + DateTime.UtcNow.Month,
            };
            db.Consultations.Add(consultation);
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { consultation.Id }, message = (string?)null });
        });

        group.MapGet("/consultations/{id:guid}/messages", async (Guid id, string? after, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var query = db.ConsultationMessages.Where(m => m.ConsultationId == id && m.Consultation.UserId == userId);
            if (Guid.TryParse(after, out var afterId))
                query = query.Where(m => m.Id.CompareTo(afterId) > 0);
            var messages = await query.OrderBy(m => m.CreatedAt).Take(50).Select(m => new { m.Id, SenderType = m.SenderType.ToString(), m.SenderName, m.Content, m.CreatedAt }).ToListAsync(ct);
            return Results.Ok(new { code = 0, data = messages, message = (string?)null });
        });

        group.MapPost("/consultations/{id:guid}/messages", async (Guid id, SendMessageRequest req, HttpContext http, AppDbContext db, CancellationToken ct) =>
        {
            var userId = GetUserId(http);
            var msg = new ConsultationMessage { Id = Guid.NewGuid(), ConsultationId = id, SenderType = ConsultationSenderType.User, Content = req.Content, SenderName = null, CreatedAt = DateTime.UtcNow };
            db.ConsultationMessages.Add(msg);
            await db.SaveChangesAsync(ct);
            return Results.Ok(new { code = 0, data = new { msg.Id }, message = (string?)null });
        });

        group.MapGet("/user/consultation-quota", async (HttpContext http, AppDbContext db) =>
        {
            var userId = GetUserId(http);
            var now = DateTime.UtcNow;
            var currentPeriod = now.Year * 100 + now.Month;
            var used = await db.Consultations.CountAsync(c => c.UserId == userId && c.Month == currentPeriod);
            return Results.Ok(new { code = 0, data = new { total = 3, used, remaining = 3 - used }, 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 record CreateConsultationRequest(Guid DoctorId);
public sealed record SendMessageRequest(string Content);
