using Netina.Domain.Enums;

namespace Netina.Api.Controllers;
public class OrderController : ICarterModule
{
    public void AddRoutes(IEndpointRouteBuilder app)
    {
        var group = app.NewVersionedApi("Order")
            .MapGroup("api/order")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser());

        group.MapGet("", GetAllAsync)
            .WithDisplayName("GetAllOrders")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders , ApplicationPermission.ManageOrders))
            .HasApiVersion(1.0);

        group.MapGet("{id}", GetAsync)
            .WithDisplayName("GetOneOrder")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ViewAllOrders, ApplicationPermission.ManageOrders))
            .HasApiVersion(1.0);

        group.MapPost("{id}/confirm", ConfirmOrderStepAsync)
            .WithDisplayName("ConfirmOrderStep")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission,  ApplicationPermission.ManageOrders))
            .HasApiVersion(1.0);

        group.MapDelete("{id}", DeleteAsync)
            .WithDisplayName("DeleteOneOrder")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
            .HasApiVersion(1.0);

        group.MapGet("{id}/invoice", GetOrderInvoiceAsync)
            .WithDisplayName("GetOrderInvoice")
            .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser().RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageOrders))
            .AllowAnonymous()
            .HasApiVersion(1.0);

    }

    private async Task<IResult> ConfirmOrderStepAsync(Guid id, [FromQuery] OrderStatus nextOrderStatus, [FromQuery]string? trackingCode, [FromServices] IMediator mediator, CancellationToken cancellationToken)
        => TypedResults.Ok(await mediator.Send(new ConfirmOrderStepCommand(id, nextOrderStatus,TrackingCode:trackingCode), cancellationToken));

    public async Task<IResult> GetAllAsync(IMediator mediator, [FromQuery]string? factorCode, [FromQuery]long? selectedDate, [FromQuery] OrderStatus? orderStatus, [FromQuery] OrderQueryDateFilter? dateFilter, [FromQuery] int page = 0, CancellationToken cancellationToken = default)
        => TypedResults.Ok(await mediator.Send(new GetOrdersQuery(Page:page, FactorCode:factorCode , SelectedDate: selectedDate, OrderStatus:orderStatus, DateFilter:dateFilter), cancellationToken));

    public async Task<IResult> GetAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
    {
        var order = await mediator.Send(new GetOrderLDtoQuery(id), cancellationToken);
        return TypedResults.Ok(order);
    }


    public async Task<IResult> DeleteAsync(IMediator mediator, Guid id, CancellationToken cancellationToken = default)
        => TypedResults.Ok(await mediator.Send(new DeleteOrderCommand(id), cancellationToken));

    private async Task<IResult> GetOrderInvoiceAsync([FromRoute] Guid id, [FromServices] IMediator mediator, CancellationToken cancellationToken)
    {
        var file = await mediator.Send(new GetOrderInvoiceCommand(id), cancellationToken);
        string fileName = $"Invoice_{id}.pdf";
        return TypedResults.File(file, "application/pdf", fileName);
    }

}
