using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SolutionErp.Application.Common.Models;
using SolutionErp.Application.Master.Suppliers.Commands.CreateSupplier;
using SolutionErp.Application.Master.Suppliers.Commands.DeleteSupplier;
using SolutionErp.Application.Master.Suppliers.Commands.ImportSuppliers;
using SolutionErp.Application.Master.Suppliers.Commands.PublishSupplier;
using SolutionErp.Application.Master.Suppliers.Commands.UpdateSupplier;
using SolutionErp.Application.Master.Suppliers.Dtos;
using SolutionErp.Application.Master.Suppliers.Queries.GetSupplier;
using SolutionErp.Application.Master.Suppliers.Queries.GetSupplierImportTemplate;
using SolutionErp.Application.Master.Suppliers.Queries.ListSuppliers;
using SolutionErp.Domain.Master;

namespace SolutionErp.Api.Controllers;

[ApiController]
[Route("api/suppliers")]
[Authorize]
public class SuppliersController(IMediator mediator) : ControllerBase
{
    // published: null = tất cả (admin quản lý thấy cả nháp) · true = chỉ NCC đã công bố (picker/consumer) · false = chỉ nháp.
    [HttpGet]
    public async Task<ActionResult<PagedResult<SupplierDto>>> List(
        [FromQuery] int page = 1, [FromQuery] int pageSize = 20,
        [FromQuery] string? search = null, [FromQuery] string? sortBy = null, [FromQuery] bool sortDesc = true,
        [FromQuery] SupplierType? type = null, [FromQuery] bool? published = null,
        CancellationToken ct = default)
        => Ok(await mediator.Send(new ListSuppliersQuery(type, published) { Page = page, PageSize = pageSize, Search = search, SortBy = sortBy, SortDesc = sortDesc }, ct));

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

    // [S57] Master write khóa Admin+CatalogManager (đọc mở cho mọi role review/test;
    // chống nhân viên sửa/xóa NCC production qua API khi menu hiện cho toàn bộ phận).
    // [S59] anh chốt (UAT "Không tự thêm dc tên NTP mới"): TẠO MỚI mở cho mọi user
    // đăng nhập — nghiệp vụ đi thầu phát sinh NCC/NTP liên tục, quick-add ngay form
    // thêm NCC vào phiếu. SỬA/XÓA vẫn khóa Admin+CatalogManager (2 action dưới).
    [HttpPost]
    public async Task<ActionResult<Guid>> Create([FromBody] CreateSupplierCommand cmd, CancellationToken ct)
    {
        var id = await mediator.Send(cmd, ct);
        return CreatedAtAction(nameof(Get), new { id }, new { id });
    }

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

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

    // [S113 D3] Công bố / ẩn 1 NCC (import v2). NHÁP (thiếu Mã NCC) → publish tay ở đây.
    // KHÔNG dùng UpdateSupplierCommand (blind absolute-set → clobber #73). Body { maNcc?, publish }.
    [Authorize(Policy = "Suppliers.Update")]
    [HttpPost("{id:guid}/publish")]
    public async Task<IActionResult> Publish(Guid id, [FromBody] PublishSupplierBody body, CancellationToken ct)
    {
        await mediator.Send(new PublishSupplierCommand(id, body.MaNcc, body.Publish), ct);
        return NoContent();
    }

    // ========== Import Excel "Database NCC" (Supplier import v2 — layout-locked ROW 4, 30 cột) ==========
    // [S113 D3] authz: policy quyền Suppliers Update (danh mục), khớp FE PermissionGuard (hết 403 non-admin).
    // Tải file mẫu (.xlsx trống, 30 token header ROW 4). Single-source ExpectedHeaderTokens (0 drift).
    [Authorize(Policy = "Suppliers.Update")]
    [HttpGet("import/template")]
    public async Task<IActionResult> ImportTemplate(CancellationToken ct)
        => File(await mediator.Send(new GetSupplierImportTemplateQuery(), ct),
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                "Mau-Database-NCC.xlsx");

    // Preview: parse + phân loại từng hàng (KHÔNG ghi DB). Header sai layout → LayoutValid=false.
    [Authorize(Policy = "Suppliers.Update")]
    [HttpPost("import/preview")]
    [RequestSizeLimit(25_000_000)]
    public async Task<ActionResult<SupplierImportPreviewDto>> ImportPreview(IFormFile file, CancellationToken ct)
    {
        if (file is null || file.Length == 0)
            return BadRequest(new { detail = "Chưa chọn file." });
        await using var stream = file.OpenReadStream();
        return Ok(await mediator.Send(new SupplierImportPreviewCommand(stream), ct));
    }

    // Confirm: ALL-OR-NOTHING upsert (dedup MST-primary + Code-backstop; blank Code = draft ẩn).
    // Body JSON = { "rows": [ ... ] } (mảng SupplierImportRowDto round-trip từ preview).
    [Authorize(Policy = "Suppliers.Update")]
    [HttpPost("import/confirm")]
    public async Task<ActionResult<SupplierImportResultDto>> ImportConfirm(
        [FromBody] SupplierImportConfirmCommand cmd, CancellationToken ct)
        => Ok(await mediator.Send(cmd, ct));
}
