using IdokladSdk.Enums;
using IdokladSdk.Models.Attachment;
using IdokladSdk.Models.Webhook;
using Idoklad.Client;

namespace Idoklad.Services;

/// <summary>
/// Integration / utility agendas: webhooks, notifications, change log, registered sales (EET),
/// unpaired documents, attachments and the system code books.
/// </summary>
public sealed class IntegrationService
{
    private readonly IdokladApiAccessor _accessor;

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

    // ---- Webhooks ----
    public Task<object?> ListWebhooksAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.WebhookClient.List().ToPageAsync(page, pageSize, ct);

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

    public async Task<object?> CreateWebhookAsync(AgendaWebhookSettingsPostModel model, CancellationToken ct)
        => (await _accessor.Api.WebhookClient.PostAsync(model, ct)).Unwrap();

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

    // ---- Notifications ----
    public Task<object?> ListNotificationsAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.NotificationClient.List().ToPageAsync(page, pageSize, ct);

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

    // ---- Change log ----
    public Task<object?> ListLogAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.LogClient.List().ToPageAsync(page, pageSize, ct);

    // ---- Registered sales (EET) ----
    public Task<object?> ListRegisteredSalesAsync(int page, int pageSize, CancellationToken ct)
        => _accessor.Api.RegisteredSaleClient.List().ToPageAsync(page, pageSize, ct);

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

    // ---- Unpaired documents ----
    public Task<object?> ListUnpairedDocumentsAsync(
        MovementType movementType, PairingDocumentType pairingDocumentType, int page, int pageSize, CancellationToken ct)
        => _accessor.Api.UnpairedDocumentClient.List(movementType, pairingDocumentType).ToPageAsync(page, pageSize, ct);

    // ---- Attachments ----
    public async Task<object?> GetAttachmentAsync(int attachmentId, bool compressed, CancellationToken ct)
        => (await _accessor.Api.AttachmentClient.GetAsync(attachmentId, compressed, ct)).Unwrap();

    public async Task<object?> GetDocumentAttachmentsAsync(int documentId, AttachmentDocumentType documentType, bool compressed, CancellationToken ct)
        => (await _accessor.Api.AttachmentClient.GetAsync(documentId, documentType, compressed, ct)).Unwrap();

    public async Task<bool> UploadAttachmentAsync(AttachmentUploadModel model, CancellationToken ct)
        => (await _accessor.Api.AttachmentClient.UploadAsync(model, ct)).Unwrap();

    public async Task<bool> DeleteAttachmentAsync(int attachmentId, CancellationToken ct)
        => (await _accessor.Api.AttachmentClient.DeleteAsync(attachmentId, ct)).Unwrap();

    public async Task<bool> DeleteDocumentAttachmentsAsync(int documentId, AttachmentDocumentType documentType, CancellationToken ct)
        => (await _accessor.Api.AttachmentClient.DeleteAsync(documentId, documentType, ct)).Unwrap();

    // ---- System code books ----
    public Task<object?> CodeBooksAsync(CancellationToken ct)
        => _accessor.Api.SystemClient.CodeBooks().ToDetailAsync(ct);

    public Task<object?> CodeBooksChangesAsync(DateTime lastCheck, CancellationToken ct)
        => _accessor.Api.SystemClient.CodeBooksChanges(lastCheck).ToDetailAsync(ct);
}
