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

namespace SolutionErp.Api.Controllers;

[ApiController]
[Route("api/leave-requests")]
[Authorize]
public class LeaveRequestsController(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 GetLeaveRequestsQuery(status, requesterUserId, page, pageSize)));

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

    [HttpPost]
    public async Task<IActionResult> Create([FromBody] CreateLeaveRequestCommand 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] UpdateLeaveRequestDraftBody body)
    {
        await mediator.Send(new UpdateLeaveRequestDraftCommand(id, body.LeaveTypeId, body.StartDate,
            body.EndDate, body.NumDays, body.Reason, body.ApprovalWorkflowId));
        return NoContent();
    }

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

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

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

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

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

    public record SetWorkflowBody(Guid ApprovalWorkflowId);

    public record UpdateLeaveRequestDraftBody(
        Guid LeaveTypeId,
        DateTime StartDate,
        DateTime EndDate,
        decimal NumDays,
        string Reason,
        Guid? ApprovalWorkflowId);

    public record WorkflowActionBody(string? Comment);
}
