using IdokladSdk.Models.CreditNote;
using IdokladSdk.Models.IssuedDocumentTemplate.Patch;
using IdokladSdk.Models.IssuedDocumentTemplate.Post;
using IdokladSdk.Models.IssuedTaxDocument.Patch;
using IdokladSdk.Models.IssuedTaxDocument.Post;
using IdokladSdk.Models.ProformaInvoice;
using IdokladSdk.Models.RecurringInvoice;
using IdokladSdk.Models.SalesOrder;
using IdokladSdk.Models.SalesReceipt;
using Idoklad.Client;

namespace Idoklad.Services;

/// <summary>
/// Sales-side documents: proforma invoices, credit notes, sales receipts, sales orders,
/// recurring invoices, issued tax documents and issued document templates.
/// </summary>
public sealed class SalesDocumentsService
{
    private readonly IdokladApiAccessor _accessor;

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

    // ---- Proforma invoices ----
    public Task<object?> ListProformaAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.ProformaInvoiceClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> ProformaDefaultAsync(CancellationToken ct)
        => (await _accessor.Api.ProformaInvoiceClient.DefaultAsync(ct)).Unwrap();

    public async Task<object?> ProformaCopyAsync(int id, CancellationToken ct)
        => (await _accessor.Api.ProformaInvoiceClient.CopyAsync(id, ct)).Unwrap();

    public async Task<object?> CreateProformaAsync(ProformaInvoicePostModel model, CancellationToken ct)
        => (await _accessor.Api.ProformaInvoiceClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateProformaAsync(ProformaInvoicePatchModel model, CancellationToken ct)
        => (await _accessor.Api.ProformaInvoiceClient.UpdateAsync(model, ct)).Unwrap();

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

    // ---- Credit notes ----
    public Task<object?> ListCreditNotesAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.CreditNoteClient.List().ToPageAsync(page, pageSize, ct);

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

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

    public async Task<object?> CreateCreditNoteAsync(CreditNotePostModel model, CancellationToken ct)
        => (await _accessor.Api.CreditNoteClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateCreditNoteAsync(CreditNotePatchModel model, CancellationToken ct)
        => (await _accessor.Api.CreditNoteClient.UpdateAsync(model, ct)).Unwrap();

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

    // ---- Sales receipts ----
    public Task<object?> ListSalesReceiptsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.SalesReceiptClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> SalesReceiptDefaultAsync(CancellationToken ct)
        => (await _accessor.Api.SalesReceiptClient.DefaultAsync(ct)).Unwrap();

    public async Task<object?> SalesReceiptCopyAsync(int id, CancellationToken ct)
        => (await _accessor.Api.SalesReceiptClient.CopyAsync(id, ct)).Unwrap();

    public async Task<object?> CreateSalesReceiptAsync(SalesReceiptPostModel model, CancellationToken ct)
        => (await _accessor.Api.SalesReceiptClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateSalesReceiptAsync(SalesReceiptPatchModel model, CancellationToken ct)
        => (await _accessor.Api.SalesReceiptClient.UpdateAsync(model, ct)).Unwrap();

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

    // ---- Sales orders ----
    public Task<object?> ListSalesOrdersAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.SalesOrderClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> SalesOrderDefaultAsync(CancellationToken ct)
        => (await _accessor.Api.SalesOrderClient.DefaultAsync(ct)).Unwrap();

    public async Task<object?> SalesOrderCopyAsync(int id, CancellationToken ct)
        => (await _accessor.Api.SalesOrderClient.CopyAsync(id, ct)).Unwrap();

    public async Task<object?> CreateSalesOrderAsync(SalesOrderPostModel model, CancellationToken ct)
        => (await _accessor.Api.SalesOrderClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateSalesOrderAsync(SalesOrderPatchModel model, CancellationToken ct)
        => (await _accessor.Api.SalesOrderClient.UpdateAsync(model, ct)).Unwrap();

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

    // ---- Recurring invoices ----
    public Task<object?> ListRecurringAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.RecurringInvoiceClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> RecurringDefaultAsync(CancellationToken ct)
        => (await _accessor.Api.RecurringInvoiceClient.DefaultAsync(ct)).Unwrap();

    public async Task<object?> RecurringCopyAsync(int id, CancellationToken ct)
        => (await _accessor.Api.RecurringInvoiceClient.CopyAsync(id, ct)).Unwrap();

    public async Task<object?> CreateRecurringAsync(RecurringInvoicePostModel model, CancellationToken ct)
        => (await _accessor.Api.RecurringInvoiceClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateRecurringAsync(RecurringInvoicePatchModel model, CancellationToken ct)
        => (await _accessor.Api.RecurringInvoiceClient.UpdateAsync(model, ct)).Unwrap();

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

    // ---- Issued tax documents ----
    public Task<object?> ListTaxDocumentsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.IssuedTaxDocumentClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> TaxDocumentDefaultAsync(int advanceInvoiceId, CancellationToken ct)
        => (await _accessor.Api.IssuedTaxDocumentClient.DefaultAsync(advanceInvoiceId, ct)).Unwrap();

    public async Task<object?> CreateTaxDocumentAsync(IssuedTaxDocumentPostModel model, CancellationToken ct)
        => (await _accessor.Api.IssuedTaxDocumentClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateTaxDocumentAsync(IssuedTaxDocumentPatchModel model, CancellationToken ct)
        => (await _accessor.Api.IssuedTaxDocumentClient.UpdateAsync(model, ct)).Unwrap();

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

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

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

    public async Task<object?> TemplateDefaultAsync(CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentTemplateClient.DefaultAsync(ct)).Unwrap();

    public async Task<object?> CreateTemplateAsync(IssuedDocumentTemplatePostModel model, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentTemplateClient.PostAsync(model, ct)).Unwrap();

    public async Task<object?> UpdateTemplateAsync(IssuedDocumentTemplatePatchModel model, CancellationToken ct)
        => (await _accessor.Api.IssuedDocumentTemplateClient.UpdateAsync(model, ct)).Unwrap();

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