using FlatRender.IdentitySvc.Application.Services.Interfaces;
using FlatRender.IdentitySvc.Models.Requests;
using FlatRender.IdentitySvc.Models.Responses;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace FlatRender.IdentitySvc.Controllers;

[ApiController]
[Route("v1/discounts")]
[Authorize]
public class DiscountsController(IDiscountService discountService) : ControllerBase
{
    [HttpPost("validate")]
    [AllowAnonymous]
    [ProducesResponseType(typeof(DiscountValidateResponse), 200)]
    public async Task<IActionResult> Validate([FromBody] ValidateDiscountRequest request)
    {
        var tenantId = GetTenantIdOrDefault();
        var result = await discountService.ValidateAsync(tenantId, request.Code, request.PlanId);
        return Ok(result);
    }

    [HttpGet]
    [ProducesResponseType(typeof(PagedResponse<DiscountResponse>), 200)]
    public async Task<IActionResult> List([FromQuery] int page = 1, [FromQuery] int pageSize = 20)
    {
        var result = await discountService.ListAsync(GetTenantId(), page, pageSize);
        return Ok(result);
    }

    [HttpPost]
    [ProducesResponseType(typeof(DiscountResponse), 201)]
    public async Task<IActionResult> Create([FromBody] CreateDiscountRequest request)
    {
        var result = await discountService.CreateAsync(GetTenantId(), request);
        return StatusCode(201, result);
    }

    [HttpPut("{id:guid}")]
    [ProducesResponseType(typeof(DiscountResponse), 200)]
    public async Task<IActionResult> Update(Guid id, [FromBody] UpdateDiscountRequest request)
    {
        var result = await discountService.UpdateAsync(GetTenantId(), id, request);
        return result == null ? NotFound() : Ok(result);
    }

    [HttpDelete("{id:guid}")]
    [ProducesResponseType(204)]
    public async Task<IActionResult> Delete(Guid id)
    {
        var ok = await discountService.DeleteAsync(GetTenantId(), id);
        return ok ? NoContent() : NotFound();
    }

    private Guid GetTenantId() => Guid.Parse(User.FindFirst("tenant_id")?.Value
        ?? throw new UnauthorizedAccessException());

    private Guid GetTenantIdOrDefault()
    {
        var claim = User.FindFirst("tenant_id")?.Value;
        return claim != null ? Guid.Parse(claim) : Guid.Empty;
    }
}
