using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SolutionErp.Application.Office;

namespace SolutionErp.Api.Controllers;

[ApiController]
[Route("api/travel-requests")]
[Authorize]
public class TravelRequestsController(IMediator mediator) : ControllerBase
{
    [HttpGet]
    public async Task<IActionResult> GetList([FromQuery] int? status, [FromQuery] Guid? requesterUserId, [FromQuery] int page = 1, [FromQuery] int pageSize = 50)
        => Ok(await mediator.Send(new GetTravelRequestsQuery(status, requesterUserId, page, pageSize)));

    [HttpGet("{id:guid}")]
    public async Task<IActionResult> GetById(Guid id)
    {
        var dto = await mediator.Send(new GetTravelRequestByIdQuery(id));
        return dto is null ? NotFound() : Ok(dto);
    }

    [HttpPost]
    public async Task<IActionResult> Create([FromBody] CreateTravelRequestCommand cmd)
    {
        var id = await mediator.Send(cmd);
        return CreatedAtAction(nameof(GetById), new { id }, new { id });
    }

    [HttpPut("{id:guid}")]
    public async Task<IActionResult> Update(Guid id, [FromBody] UpdateTravelRequestBody body)
    {
        await mediator.Send(new UpdateTravelRequestDraftCommand(id, body.Destination, body.StartDate,
            body.EndDate, body.NumDays, body.Purpose, body.EstimatedCost, body.ApprovalWorkflowId));
        return NoContent();
    }

    [HttpPost("{id:guid}/submit")]
    public async Task<IActionResult> Submit(Guid id)
    {
        await mediator.Send(new SubmitTravelRequestCommand(id));
        return NoContent();
    }

    [HttpPost("{id:guid}/approve")]
    public async Task<IActionResult> Approve(Guid id, [FromBody] ApprovalActionBody body)
    {
        await mediator.Send(new ApproveTravelRequestCommand(id, body.Comment));
        return NoContent();
    }

    [HttpPost("{id:guid}/reject")]
    public async Task<IActionResult> Reject(Guid id, [FromBody] ApprovalActionBody body)
    {
        await mediator.Send(new RejectTravelRequestCommand(id, body.Comment));
        return NoContent();
    }

    [HttpPost("{id:guid}/return")]
    public async Task<IActionResult> Return(Guid id, [FromBody] ApprovalActionBody body)
    {
        await mediator.Send(new ReturnTravelRequestCommand(id, body.Comment));
        return NoContent();
    }

    [HttpPut("{id:guid}/workflow")]
    public async Task<IActionResult> SetWorkflow(Guid id, [FromBody] SetWorkflowBody body)
    {
        await mediator.Send(new SetTravelRequestWorkflowCommand(id, body.ApprovalWorkflowId));
        return NoContent();
    }

    public record SetWorkflowBody(Guid ApprovalWorkflowId);

    public record UpdateTravelRequestBody(
        string Destination,
        DateTime StartDate,
        DateTime EndDate,
        int NumDays,
        string Purpose,
        decimal? EstimatedCost,
        Guid? ApprovalWorkflowId);

    public record ApprovalActionBody(string? Comment);
}
