using Microsoft.AspNetCore.Mvc;
using ROLAC.API.Authorization;
using ROLAC.API.DTOs.Payee;
using ROLAC.API.Services;

namespace ROLAC.API.Controllers;

[ApiController]
[Route("api/payee-1099")]
[HasPermission(Modules.Form1099, PermissionActions.Read)]
public class Payee1099Controller : ControllerBase
{
    private readonly IPayee1099Service _svc;
    public Payee1099Controller(IPayee1099Service svc) => _svc = svc;

    [HttpGet]
    public async Task<IActionResult> GetAll([FromQuery] bool includeInactive = false)
        => Ok(await _svc.GetAllAsync(includeInactive));

    [HttpGet("{id:int}")]
    public async Task<IActionResult> GetById(int id)
        => await _svc.GetByIdAsync(id) is { } dto ? Ok(dto) : NotFound();

    [HttpPost]
    [HasPermission(Modules.Form1099, PermissionActions.Write)]
    public async Task<IActionResult> Create([FromBody] SavePayee1099Request r)
        => Ok(new { id = await _svc.CreateAsync(r) });

    [HttpPut("{id:int}")]
    [HasPermission(Modules.Form1099, PermissionActions.Write)]
    public async Task<IActionResult> Update(int id, [FromBody] SavePayee1099Request r)
    { await _svc.UpdateAsync(id, r); return NoContent(); }

    [HttpDelete("{id:int}")]
    [HasPermission(Modules.Form1099, PermissionActions.Delete)]
    public async Task<IActionResult> Delete(int id)
    { await _svc.DeleteAsync(id); return NoContent(); }

    // Full TIN reveal is gated on Write (a stronger right than Read).
    [HttpGet("{id:int}/tin")]
    [HasPermission(Modules.Form1099, PermissionActions.Write)]
    public async Task<IActionResult> RevealTin(int id)
        => Ok(new { tin = await _svc.RevealTinAsync(id) });

    // Mirrors the expense-receipt upload: multipart form file, size-limited, type-checked.
    [HttpPost("{id:int}/w9")]
    [HasPermission(Modules.Form1099, PermissionActions.Write)]
    [RequestSizeLimit(10_485_760)]
    public async Task<IActionResult> UploadW9(int id, IFormFile file)
    {
        if (file is null || file.Length == 0) return BadRequest(new { message = "No file." });
        var allowed = new[] { "image/jpeg", "image/png", "image/webp", "application/pdf" };
        if (!allowed.Contains(file.ContentType)) return BadRequest(new { message = "Unsupported file type." });
        try
        {
            await using var stream = file.OpenReadStream();
            await _svc.SaveW9Async(id, stream, file.FileName);
            return NoContent();
        }
        catch (KeyNotFoundException) { return NotFound(); }
    }

    // Class-level Read gate covers viewing the stored W-9 (mirrors the receipt GET).
    [HttpGet("{id:int}/w9")]
    public async Task<IActionResult> GetW9(int id)
    {
        var result = await _svc.OpenW9Async(id);
        if (result is null) return NotFound();
        return File(result.Value.stream, result.Value.contentType);
    }
}
