using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SolutionErp.Application.Common.Models;
using SolutionErp.Application.Users;

namespace SolutionErp.Api.Controllers;

[ApiController]
[Route("api/users")]
[Authorize(Policy = "Users.Read")]
public class UsersController(IMediator mediator) : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<PagedResult<UserDto>>> List(
        [FromQuery] int page = 1, [FromQuery] int pageSize = 20,
        [FromQuery] string? search = null, [FromQuery] bool sortDesc = true,
        CancellationToken ct = default)
        => Ok(await mediator.Send(new ListUsersQuery { Page = page, PageSize = pageSize, Search = search, SortDesc = sortDesc }, ct));

    [HttpGet("{id:guid}")]
    public async Task<ActionResult<UserDto>> Get(Guid id, CancellationToken ct)
        => Ok(await mediator.Send(new GetUserQuery(id), ct));

    [HttpPost]
    [Authorize(Policy = "Users.Create")]
    public async Task<ActionResult<object>> Create([FromBody] CreateUserCommand cmd, CancellationToken ct)
    {
        var id = await mediator.Send(cmd, ct);
        return CreatedAtAction(nameof(Get), new { id }, new { id });
    }

    [HttpPut("{id:guid}")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserCommand cmd, CancellationToken ct)
    {
        if (id != cmd.Id) return BadRequest(new { detail = "ID không khớp" });
        await mediator.Send(cmd, ct);
        return NoContent();
    }

    [HttpPut("{id:guid}/roles")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> AssignRoles(Guid id, [FromBody] AssignRolesBody body, CancellationToken ct)
    {
        await mediator.Send(new AssignRolesCommand(id, body.Roles), ct);
        return NoContent();
    }

    [HttpPost("{id:guid}/reset-password")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> ResetPassword(Guid id, [FromBody] ResetPasswordBody body, CancellationToken ct)
    {
        await mediator.Send(new ResetPasswordCommand(id, body.NewPassword), ct);
        return NoContent();
    }

    [HttpPost("{id:guid}/unlock")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> Unlock(Guid id, CancellationToken ct)
    {
        await mediator.Send(new UnlockUserCommand(id), ct);
        return NoContent();
    }

    // 2-stage department approval (Phase 9): admin toggle bypass-review per user.
    [HttpPatch("{id:guid}/bypass-review")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> SetBypassReview(
        Guid id, [FromBody] SetBypassReviewBody body, CancellationToken ct)
    {
        await mediator.Send(new SetUserBypassReviewCommand(id, body.CanBypassReview), ct);
        return NoContent();
    }

    // N-stage workflow inner step (Mig 18): admin set cấp chức danh user
    // (1=NV, 2=PP, 3=TP, null=admin/external). Body PositionLevel int? — null
    // sẽ clear PositionLevel của user.
    [HttpPatch("{id:guid}/position-level")]
    [Authorize(Policy = "Users.Update")]
    public async Task<IActionResult> SetPositionLevel(
        Guid id, [FromBody] SetPositionLevelBody body, CancellationToken ct)
    {
        await mediator.Send(new SetUserPositionLevelCommand(id, body.PositionLevel), ct);
        return NoContent();
    }

    // Mig 31 (S23 t1 Plan K Chunk D) — DELETED PATCH F2 endpoint per-Drafter.
    // F2 semantic + storage refactor sang ApprovalWorkflowLevels per-Approver
    // slot (AllowApproverSkipToFinal, admin opt-in qua Workflow Designer).
    // Plan K backout zombie endpoint NoOp.
}

public record AssignRolesBody(List<string> Roles);
public record ResetPasswordBody(string NewPassword);
public record SetBypassReviewBody(bool CanBypassReview);
public record SetPositionLevelBody(int? PositionLevel);
