using System.Security.Claims;
using Health.Application.Admin;

namespace Health.WebApi.Endpoints;

public static class AdminEndpoints
{
    public static void MapAdminEndpoints(this WebApplication app)
    {
        var group = app.MapGroup("/api/admin").RequireAuthorization();
        group.AddEndpointFilter(async (context, next) =>
            GetRole(context.HttpContext) == "Admin"
                ? await next(context)
                : Results.Json(new { code = 403, data = (object?)null, message = "仅管理员可访问" }, statusCode: 403));

        group.MapGet("/doctors", async (IAdminService admin, CancellationToken ct) => ToResult(await admin.ListDoctorsAsync(ct)));
        group.MapPost("/doctors", async (AddDoctorRequest request, IAdminService admin, CancellationToken ct) =>
            ToResult(await admin.AddDoctorAsync(new AddDoctorCommand(request.Phone, request.Name, request.Title, request.Department, request.ProfessionalDirection), ct)));
        group.MapPut("/doctors/{id:guid}", async (Guid id, UpdateDoctorRequest request, IAdminService admin, CancellationToken ct) =>
            ToResult(await admin.UpdateDoctorAsync(id, new UpdateDoctorCommand(request.Phone, request.Name, request.Title, request.Department, request.ProfessionalDirection), ct)));
        group.MapPut("/doctors/{id:guid}/disable", async (Guid id, IAdminService admin, CancellationToken ct) => ToResult(await admin.ToggleDoctorAsync(id, ct)));
        group.MapDelete("/doctors/{id:guid}", async (Guid id, IAdminService admin, CancellationToken ct) => ToResult(await admin.DeleteDoctorAsync(id, ct)));
        group.MapGet("/patients", async (IAdminService admin, string? search, int? page, int? pageSize, CancellationToken ct) =>
            ToResult(await admin.ListPatientsAsync(search, page ?? 1, pageSize ?? 20, ct)));
    }

    private static string GetRole(HttpContext http) =>
        http.User.FindFirst("Role")?.Value ?? http.User.FindFirst(ClaimTypes.Role)?.Value ?? "User";
    private static IResult ToResult(AdminResult result) => Results.Ok(new { code = result.Code, data = result.Data, message = result.Message });
}

public sealed record AddDoctorRequest(string Phone, string Name, string? Title, string? Department, string? ProfessionalDirection);
public sealed record UpdateDoctorRequest(string? Phone, string? Name, string? Title, string? Department, string? ProfessionalDirection);
