using IdokladSdk.Models.BankStatement.Patch;
using IdokladSdk.Models.BankStatement.Post;
using IdokladSdk.Models.IssuedDocumentPayment;
using IdokladSdk.Models.ReceivedDocumentPayments;
using Idoklad.Client;

namespace Idoklad.Services;

/// <summary>
/// Payments and bank statements: bank statements, issued document payments and received document
/// payments.
/// </summary>
public sealed class PaymentsService
{
    private readonly IdokladApiAccessor _accessor;

    public PaymentsService(IdokladApiAccessor accessor) => _accessor = accessor;

    // ---- Bank statements ----
    public Task<object?> ListBankStatementsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.BankStatementClient.List().ToPageAsync(page, pageSize, ct);

    public Task<object?> BankStatementDetailAsync(int id, CancellationToken ct)
        => _accessor.Api.BankStatementClient.Detail(id).ToDetailAsync(ct);

    public async Task<object?> CreateBankStatementAsync(BankStatementPostModel model, CancellationToken ct)
        => (await _accessor.Api.BankStatementClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateBankStatementAsync(BankStatementPatchModel model, CancellationToken ct)
        => (await _accessor.Api.BankStatementClient.UpdateAsync(model, ct)).Unwrap();

    public async Task<bool> DeleteBankStatementAsync(int id, CancellationToken ct)
        => (await _accessor.Api.BankStatementClient.DeleteAsync(id, ct)).Unwrap();

    // ---- Issued document payments ----
    public Task<object?> ListIssuedPaymentsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.IssuedDocumentPaymentClient.List().ToPageAsync(page, pageSize, ct);

    public Task<object?> IssuedPaymentDetailAsync(int id, CancellationToken ct)
        => _accessor.Api.IssuedDocumentPaymentClient.Detail(id).ToDetailAsync(ct);

    public async Task<object?> IssuedPaymentDefaultAsync(int invoiceId, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentPaymentClient.DefaultAsync(invoiceId, ct)).Unwrap();

    public async Task<object?> CreateIssuedPaymentAsync(IssuedDocumentPaymentPostModel model, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentPaymentClient.PostAsync(model, ct)).Unwrap();

    public async Task<bool> DeleteIssuedPaymentAsync(int id, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentPaymentClient.DeleteAsync(id, ct)).Unwrap();

    public async Task<bool> FullyUnpayIssuedAsync(int invoiceId, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentPaymentClient.FullyUnpayAsync(invoiceId, ct)).Unwrap();

    // ---- Received document payments ----
    public Task<object?> ListReceivedPaymentsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.ReceivedDocumentPaymentsClient.List().ToPageAsync(page, pageSize, ct);

    public Task<object?> ReceivedPaymentDetailAsync(int id, CancellationToken ct)
        => _accessor.Api.ReceivedDocumentPaymentsClient.Detail(id).ToDetailAsync(ct);

    public async Task<object?> ReceivedPaymentDefaultAsync(int invoiceId, CancellationToken ct)
        => (await _accessor.Api.ReceivedDocumentPaymentsClient.DefaultAsync(invoiceId, ct)).Unwrap();

    public async Task<object?> CreateReceivedPaymentAsync(ReceivedDocumentPaymentPostModel model, CancellationToken ct)
        => (await _accessor.Api.ReceivedDocumentPaymentsClient.PostAsync(model, ct)).Unwrap();

    public async Task<bool> DeleteReceivedPaymentAsync(int id, CancellationToken ct)
        => (await _accessor.Api.ReceivedDocumentPaymentsClient.DeleteAsync(id, ct)).Unwrap();

    public async Task<bool> FullyUnpayReceivedAsync(int invoiceId, CancellationToken ct)
        => (await _accessor.Api.ReceivedDocumentPaymentsClient.FullyUnpayAsync(invoiceId, ct)).Unwrap();
}
