using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Csob.Models;
using Csob.Services;

namespace Csob.Controllers;

/// <summary>PISP – standing-order initiation and its authorization (sign) flow. Requires the ČSOB credential headers.</summary>
[ApiController]
[Route("standing-orders")]
[Produces("application/json")]
[Tags("PISP – Standing orders")]
public sealed class StandingOrdersController : ControllerBase
{
    private readonly StandingOrdersService _service;

    public StandingOrdersController(StandingOrdersService service) => _service = service;

    /// <summary>Initiate a standing order.</summary>
    [HttpPost]
    public async Task<IActionResult> Initiate([FromBody] StandingOrderInitiationRequest request, CancellationToken ct)
        => Ok(await _service.InitiateAsync(request, ct));

    /// <summary>Get the standing-order detail.</summary>
    [HttpGet("{id}")]
    public async Task<IActionResult> Detail(string id, CancellationToken ct)
        => Ok(await _service.DetailAsync(id, ct));

    /// <summary>Get the standing-order instruction status.</summary>
    [HttpGet("{id}/status")]
    public async Task<IActionResult> Status(string id, CancellationToken ct)
        => Ok(await _service.StatusAsync(id, ct));

    /// <summary>Cancel a standing order.</summary>
    [HttpDelete("{id}")]
    public async Task<IActionResult> Cancel(string id, CancellationToken ct)
        => Ok(await _service.CancelAsync(id, ct));

    /// <summary>Start the authorization (SCA) of a standing order. Returns the PSU redirect details.</summary>
    [HttpPost("{id}/sign/{signId}")]
    public async Task<IActionResult> StartSign(string id, string signId, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] JsonNode? body, CancellationToken ct)
        => Ok(await _service.StartSignAsync(id, signId, body, ct));

    /// <summary>Get the current state of an authorization (sign) transaction.</summary>
    [HttpGet("{id}/sign/{signId}")]
    public async Task<IActionResult> SignStatus(string id, string signId, CancellationToken ct)
        => Ok(await _service.SignStatusAsync(id, signId, ct));

    /// <summary>Finalize an authorization (sign) transaction.</summary>
    [HttpPut("{id}/sign/{signId}")]
    public async Task<IActionResult> FinalizeSign(string id, string signId, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] JsonNode? body, CancellationToken ct)
        => Ok(await _service.FinalizeSignAsync(id, signId, body, ct));
}
