using ERPCore.Dtos.Common;
using ERPCore.Dtos.Hrm;
using ERPCore.Dtos.Users;
using ERPCore.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;

namespace ERPCore.Controllers;

/// <summary>
/// User management: local shadow `User` list/detail + role assignment, and
/// account creation orchestrated against AuthHex (see <see cref="IUserManagementService.CreateAsync"/>).
/// </summary>
[Route("api/v1/users")]
public sealed class UsersController : ApiControllerBase
{
    private readonly IUserManagementService _users;
    private readonly IEmployeeUserLinkService _links;

    public UsersController(IUserManagementService users, IEmployeeUserLinkService links)
    {
        _users = users;
        _links = links;
    }

    /// <summary>Advisory forward-direction lookup: does a Staff record already exist with this email? (docs/12-BACKEND-HRM.md A.5)</summary>
    [HttpGet("email-lookup")]
    [ProducesResponseType(typeof(EmployeeMatchResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<EmployeeMatchResponse>> EmailLookup([FromQuery] string email, CancellationToken ct)
        => Ok(new EmployeeMatchResponse(await _links.FindStaffCandidateByEmailAsync(email, ct)));

    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<ManagedUserDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<PagedResponse<ManagedUserDto>>> List([FromQuery] PageQuery query, CancellationToken ct)
        => Ok(await _users.ListAsync(query, ct));

    /// <summary>AuthHex UserType options for the create-user form's select.</summary>
    [HttpGet("user-types")]
    [ProducesResponseType(typeof(List<UserTypeOptionDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<List<UserTypeOptionDto>>> ListUserTypes(CancellationToken ct)
        => Ok(await _users.ListUserTypesAsync(ct));

    [HttpGet("{userId:int}")]
    [ProducesResponseType(typeof(ManagedUserDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<ManagedUserDto>> GetById(int userId, CancellationToken ct)
    {
        var result = await _users.GetAsync(userId, ct);
        return result is null ? NotFound() : Ok(result);
    }

    [HttpPost]
    [ProducesResponseType(typeof(ManagedUserDto), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<ActionResult<ManagedUserDto>> Create([FromBody] CreateUserRequest request, CancellationToken ct)
    {
        var result = await _users.CreateAsync(request, ct);
        return Created($"/api/v1/users/{result.UserId}", result);
    }

    [HttpPut("{userId:int}/role")]
    [ProducesResponseType(typeof(ManagedUserDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<ManagedUserDto>> UpdateRole(int userId, [FromBody] UpdateUserRoleRequest request, CancellationToken ct)
        => Ok(await _users.UpdateRoleAsync(userId, request, ct));
}
