using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SolutionErp.Application.Common.Models;
using SolutionErp.Application.Hrm;
using SolutionErp.Application.Hrm.Dtos;
using SolutionErp.Domain.Hrm;

namespace SolutionErp.Api.Controllers;

// Phase 10.1 G-H1 Task 4 (S33) — REST endpoint cho Hồ sơ Nhân sự.
// 5 main endpoint Phase 1 minimal: List / Get / Create / Update / Delete.
// Satellite endpoint (WorkHistory/Education/FamilyRelation/Skill/Document
// CRUD) DEFER Phase 1.5.
//
// Phase 1.5 S34 — per-action policy wired (Reviewer recommend gotcha #44 mitigation):
//   GET    → "Hrm_HoSo.Read"
//   POST   → "Hrm_HoSo.Create"
//   PUT    → "Hrm_HoSo.Update"
//   DELETE → "Hrm_HoSo.Delete"
// Class-level Read policy default — non-admin role thiếu Read sẽ 403 silent
// (cross-ref gotcha #44 — FE PermissionGuard wrap để tránh silent UX).
[ApiController]
[Route("api/employees")]
[Authorize(Policy = "Hrm_HoSo.Read")]
public class EmployeesController(IMediator mediator) : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<PagedResult<EmployeeProfileListItemDto>>> List(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20,
        [FromQuery] string? search = null,
        [FromQuery] bool sortDesc = true,
        [FromQuery] EmployeeStatus? status = null,
        [FromQuery] Guid? departmentId = null,
        CancellationToken ct = default)
        => Ok(await mediator.Send(new ListEmployeesQuery(status, departmentId)
        { Page = page, PageSize = pageSize, Search = search, SortDesc = sortDesc }, ct));

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

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

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

    [HttpDelete("{id:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> Delete(Guid id, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeProfileCommand(id), ct);
        return NoContent();
    }

    // Phase 1.5 Item 3 (S34) — 5 satellite CRUD endpoint scaffold.
    // FE inline form satellite DEFER S35. File upload IFileStorage wire body DEFER.
    // Per-action policy inherit class-level Read + override Create/Update/Delete.

    #region WorkHistory satellite

    [HttpPost("{id:guid}/work-history")]
    [Authorize(Policy = "Hrm_HoSo.Create")]
    public async Task<ActionResult<object>> CreateWorkHistory(
        Guid id, [FromBody] CreateEmployeeWorkHistoryCommand cmd, CancellationToken ct)
    {
        if (id != cmd.EmployeeProfileId) return BadRequest(new { detail = "Employee ID không khớp" });
        var newId = await mediator.Send(cmd, ct);
        return Ok(new { id = newId });
    }

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

    [HttpDelete("{id:guid}/work-history/{satId:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> DeleteWorkHistory(Guid id, Guid satId, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeWorkHistoryCommand(satId), ct);
        return NoContent();
    }

    #endregion

    #region Education satellite

    [HttpPost("{id:guid}/education")]
    [Authorize(Policy = "Hrm_HoSo.Create")]
    public async Task<ActionResult<object>> CreateEducation(
        Guid id, [FromBody] CreateEmployeeEducationCommand cmd, CancellationToken ct)
    {
        if (id != cmd.EmployeeProfileId) return BadRequest(new { detail = "Employee ID không khớp" });
        var newId = await mediator.Send(cmd, ct);
        return Ok(new { id = newId });
    }

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

    [HttpDelete("{id:guid}/education/{satId:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> DeleteEducation(Guid id, Guid satId, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeEducationCommand(satId), ct);
        return NoContent();
    }

    #endregion

    #region FamilyRelation satellite

    [HttpPost("{id:guid}/family-relations")]
    [Authorize(Policy = "Hrm_HoSo.Create")]
    public async Task<ActionResult<object>> CreateFamilyRelation(
        Guid id, [FromBody] CreateEmployeeFamilyRelationCommand cmd, CancellationToken ct)
    {
        if (id != cmd.EmployeeProfileId) return BadRequest(new { detail = "Employee ID không khớp" });
        var newId = await mediator.Send(cmd, ct);
        return Ok(new { id = newId });
    }

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

    [HttpDelete("{id:guid}/family-relations/{satId:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> DeleteFamilyRelation(Guid id, Guid satId, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeFamilyRelationCommand(satId), ct);
        return NoContent();
    }

    #endregion

    #region Skill satellite

    [HttpPost("{id:guid}/skills")]
    [Authorize(Policy = "Hrm_HoSo.Create")]
    public async Task<ActionResult<object>> CreateSkill(
        Guid id, [FromBody] CreateEmployeeSkillCommand cmd, CancellationToken ct)
    {
        if (id != cmd.EmployeeProfileId) return BadRequest(new { detail = "Employee ID không khớp" });
        var newId = await mediator.Send(cmd, ct);
        return Ok(new { id = newId });
    }

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

    [HttpDelete("{id:guid}/skills/{satId:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> DeleteSkill(Guid id, Guid satId, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeSkillCommand(satId), ct);
        return NoContent();
    }

    #endregion

    #region Document satellite

    [HttpPost("{id:guid}/documents")]
    [Authorize(Policy = "Hrm_HoSo.Create")]
    public async Task<ActionResult<object>> CreateDocument(
        Guid id, [FromBody] CreateEmployeeDocumentCommand cmd, CancellationToken ct)
    {
        if (id != cmd.EmployeeProfileId) return BadRequest(new { detail = "Employee ID không khớp" });
        var newId = await mediator.Send(cmd, ct);
        return Ok(new { id = newId });
    }

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

    [HttpDelete("{id:guid}/documents/{satId:guid}")]
    [Authorize(Policy = "Hrm_HoSo.Delete")]
    public async Task<IActionResult> DeleteDocument(Guid id, Guid satId, CancellationToken ct)
    {
        await mediator.Send(new DeleteEmployeeDocumentCommand(satId), ct);
        return NoContent();
    }

    #endregion
}
