<?php

// this file is @generated
declare(strict_types=1);

namespace Svix\Api;

use Svix\Exception\ApiException;
use Svix\Models\EmptyResponse;
use Svix\Models\ListResponseEndpointMessageOut;
use Svix\Models\ListResponseMessageAttemptOut;
use Svix\Models\ListResponseMessageEndpointOut;
use Svix\Models\MessageAttemptOut;
use Svix\Request\SvixHttpClient;

class MessageAttempt
{
    public function __construct(
        private readonly SvixHttpClient $client,
    ) {
    }

    /**
     * List attempts by endpoint id.
     *
     * Note that by default this endpoint is limited to retrieving 90 days' worth of data
     * relative to now or, if an iterator is provided, 90 days before/after the time indicated
     * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
     * set the `before` or `after` parameter as appropriate.
     *
     * @throws ApiException
     */
    public function listByEndpoint(
        string $appId,
        string $endpointId,
        MessageAttemptListByEndpointOptions $options = new MessageAttemptListByEndpointOptions(),
    ): ListResponseMessageAttemptOut {
        $request = $this->client->newReq('GET', "/api/v1/app/{$appId}/attempt/endpoint/{$endpointId}");
        $request->setQueryParam('limit', $options->limit);
        $request->setQueryParam('iterator', $options->iterator);
        $request->setQueryParam('status', $options->status);
        $request->setQueryParam('status_code_class', $options->statusCodeClass);
        $request->setQueryParam('channel', $options->channel);
        $request->setQueryParam('tag', $options->tag);
        $request->setQueryParam('before', $options->before);
        $request->setQueryParam('after', $options->after);
        $request->setQueryParam('with_content', $options->withContent);
        $request->setQueryParam('with_msg', $options->withMsg);
        $request->setQueryParam('expanded_statuses', $options->expandedStatuses);
        $request->setQueryParam('event_types', $options->eventTypes);
        $res = $this->client->send($request);

        return ListResponseMessageAttemptOut::fromJson($res);
    }

    /**
     * List attempts by message ID.
     *
     * Note that by default this endpoint is limited to retrieving 90 days' worth of data
     * relative to now or, if an iterator is provided, 90 days before/after the time indicated
     * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
     * set the `before` or `after` parameter as appropriate.
     *
     * @throws ApiException
     */
    public function listByMsg(
        string $appId,
        string $msgId,
        MessageAttemptListByMsgOptions $options = new MessageAttemptListByMsgOptions(),
    ): ListResponseMessageAttemptOut {
        $request = $this->client->newReq('GET', "/api/v1/app/{$appId}/attempt/msg/{$msgId}");
        $request->setQueryParam('limit', $options->limit);
        $request->setQueryParam('iterator', $options->iterator);
        $request->setQueryParam('status', $options->status);
        $request->setQueryParam('status_code_class', $options->statusCodeClass);
        $request->setQueryParam('channel', $options->channel);
        $request->setQueryParam('tag', $options->tag);
        $request->setQueryParam('endpoint_id', $options->endpointId);
        $request->setQueryParam('before', $options->before);
        $request->setQueryParam('after', $options->after);
        $request->setQueryParam('with_content', $options->withContent);
        $request->setQueryParam('expanded_statuses', $options->expandedStatuses);
        $request->setQueryParam('event_types', $options->eventTypes);
        $res = $this->client->send($request);

        return ListResponseMessageAttemptOut::fromJson($res);
    }

    /**
     * List messages for a particular endpoint.
     *
     * Additionally includes metadata about the latest message attempt.
     * The `before` parameter lets you filter all items created before a certain date and is ignored if an iterator is passed.
     *
     * Note that by default this endpoint is limited to retrieving 90 days' worth of data
     * relative to now or, if an iterator is provided, 90 days before/after the time indicated
     * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
     * set the `before` or `after` parameter as appropriate.
     *
     * @throws ApiException
     */
    public function listAttemptedMessages(
        string $appId,
        string $endpointId,
        MessageAttemptListAttemptedMessagesOptions $options = new MessageAttemptListAttemptedMessagesOptions(),
    ): ListResponseEndpointMessageOut {
        $request = $this->client->newReq('GET', "/api/v1/app/{$appId}/endpoint/{$endpointId}/msg");
        $request->setQueryParam('limit', $options->limit);
        $request->setQueryParam('iterator', $options->iterator);
        $request->setQueryParam('channel', $options->channel);
        $request->setQueryParam('tag', $options->tag);
        $request->setQueryParam('status', $options->status);
        $request->setQueryParam('before', $options->before);
        $request->setQueryParam('after', $options->after);
        $request->setQueryParam('with_content', $options->withContent);
        $request->setQueryParam('expanded_statuses', $options->expandedStatuses);
        $request->setQueryParam('event_types', $options->eventTypes);
        $res = $this->client->send($request);

        return ListResponseEndpointMessageOut::fromJson($res);
    }

    /**
     * List endpoints attempted by a given message.
     *
     * Additionally includes metadata about the latest message attempt.
     * By default, endpoints are listed in ascending order by ID.
     *
     * @throws ApiException
     */
    public function listAttemptedDestinations(
        string $appId,
        string $msgId,
        MessageAttemptListAttemptedDestinationsOptions $options = new MessageAttemptListAttemptedDestinationsOptions(),
    ): ListResponseMessageEndpointOut {
        $request = $this->client->newReq('GET', "/api/v1/app/{$appId}/msg/{$msgId}/endpoint");
        $request->setQueryParam('limit', $options->limit);
        $request->setQueryParam('iterator', $options->iterator);
        $res = $this->client->send($request);

        return ListResponseMessageEndpointOut::fromJson($res);
    }

    /**
     * `msg_id`: Use a message id or a message `eventId`.
     *
     * @throws ApiException
     */
    public function get(
        string $appId,
        string $msgId,
        string $attemptId,
        MessageAttemptGetOptions $options = new MessageAttemptGetOptions(),
    ): MessageAttemptOut {
        $request = $this->client->newReq('GET', "/api/v1/app/{$appId}/msg/{$msgId}/attempt/{$attemptId}");
        $request->setQueryParam('expanded_statuses', $options->expandedStatuses);
        $res = $this->client->send($request);

        return MessageAttemptOut::fromJson($res);
    }

    /**
     * Deletes the given attempt's response body.
     *
     * Useful when an endpoint accidentally returned sensitive content.
     * The message can't be replayed or resent once its payload has been deleted or expired.
     *
     * @throws ApiException
     */
    public function expungeContent(
        string $appId,
        string $msgId,
        string $attemptId,
    ): void {
        $request = $this->client->newReq('DELETE', "/api/v1/app/{$appId}/msg/{$msgId}/attempt/{$attemptId}/content");
        $res = $this->client->sendNoResponseBody($request);
    }

    /**
     * Resend a message to the specified endpoint.
     *
     * @throws ApiException
     */
    public function resend(
        string $appId,
        string $msgId,
        string $endpointId,
        MessageAttemptResendOptions $options = new MessageAttemptResendOptions(),
    ): EmptyResponse {
        $request = $this->client->newReq('POST', "/api/v1/app/{$appId}/msg/{$msgId}/endpoint/{$endpointId}/resend");
        $request->setHeaderParam('idempotency-key', $options->idempotencyKey);
        $res = $this->client->send($request);

        return EmptyResponse::fromJson($res);
    }
}
