<?php

use DocuSign\eSign\Model\EnvelopeDefinition;
use DocuSign\eSign\Api\EnvelopesApi;
use DocuSign\eSign\Client\ApiException;
use DocuSign\eSign\Model\Envelope;
use DocuSign\eSign\Model\Signer;
use DocuSign\eSign\Api\EnvelopesApi\GetEnvelopeOptions;
use Docusign\eSign\Api\EnvelopesApi\UpdateOptions;
use DocuSign\eSign\Model\Recipients;
use DocuSign\eSign\Api\UsersApi;
use DocuSign\eSign\Model\SenderEmailNotifications;
use DocuSign\eSign\Model\UserSettingsInformation;

class Agro_DocuSign_Email
{
    protected EnvelopeDefinition $envelopeDefinition;
    protected EnvelopesApi $envelopesApi;
    protected Agro_DocuSign_Auth $docuSignAuth;
    /**
     *  @param Signer[] $signatarios
     */
    protected array $signatarios = [];
    
    /**
     * __construct
     */
    public function __construct()
    {
        $this->docuSignAuth = new Agro_DocuSign_Auth(Agro_DocuSign_Auth::$docusignBasePath);
        $token = $this->docuSignAuth->getAccessTokenByJWTUser();
        $this->docuSignAuth->getApiClient()->getConfig()->addDefaultHeader('Authorization', 'Bearer ' . $token);

        $this->envelopeDefinition = new EnvelopeDefinition();
        $this->envelopesApi = new EnvelopesApi($this->docuSignAuth->getApiClient());
    }

    /**
     * Define que o remetente não receberá as notificações por e-mail quando o envelope for concluído e
     * quando o(s) destinatário(s) visualiza(m) pela primeira vez o envelope.
     */
    private function setSenderEmailNotifications(): void
    {
        $senderEmailNotifications = new SenderEmailNotifications();
        $senderEmailNotifications->setEnvelopeComplete('false');
        $senderEmailNotifications->setRecipientViewed('false');
        $senderEmailNotifications->setDeliveryFailed('false');
        
        $userSettingsInformation = new UserSettingsInformation();
        $userSettingsInformation->setSenderEmailNotifications($senderEmailNotifications);

        $usersApi = new UsersApi($this->docuSignAuth->getApiClient());
        $usersApi->updateSettings(Agro_DocuSign_Auth::$docusignApiAccountId, Agro_DocuSign_Auth::$docusignUserId, $userSettingsInformation);
    }

    /**
     * Adiciona as configurações de template e signatarios no envelope
     */
    protected function configurarSignatarios() {}

        
    /**
     * Cria o envelope e o envia para os signatários
     *
     * @return string|null
     */
    public function enviar($isRascunho = false): ?string
    {
        $this->configurarSignatarios();

        if ($isRascunho) {
            $this->envelopeDefinition->setStatus(Seguro_Model_PropostasDocusign::STATUS_CREATED);
        } else {
            $this->envelopeDefinition->setStatus(Seguro_Model_PropostasDocusign::STATUS_SENT);
        }

        try {
            $results = $this->envelopesApi->createEnvelope(Agro_DocuSign_Auth::$docusignApiAccountId, $this->envelopeDefinition);
        } catch (ApiException $e) {
            throw new Exception("Erro ao criar o envelope. \n{$e->getMessage()}");
        }

        return $results->getEnvelopeId();
    }

    /**
     * Retorna o envelope
     *
     * @param  string $idEnvelope
     * @return Envelope
     */
    public function getEnvelope(string $idEnvelope): Envelope
    {
        $options = new GetEnvelopeOptions();
        $options->setInclude("recipients");
        return $this->envelopesApi->getEnvelope(Agro_DocuSign_Auth::$docusignApiAccountId, $idEnvelope, $options);
    }

    /**
     * Retorna o documento e o salva no diretório /upload_files/docusign/
     *
     * @param  string $idDocumento
     * @param  string $idEnvelope
     * @return SplFileObject|null
     */
    public function getDocumento(string $idEnvelope, string $idDocumento = '1'): ?SplFileObject
    {
        $documento = $this->envelopesApi->getDocument(Agro_DocuSign_Auth::$docusignApiAccountId, $idDocumento, $idEnvelope);
        if (!$documento) {
            return null;
        }

        file_put_contents(APPLICATION_PATH . "/upload_files/docusign/{$idDocumento}-{$idEnvelope}.pdf", file_get_contents($documento->getPathname()));
        return $documento;
    }

    public function getEnvelopesApi(): EnvelopesApi
    {
        return $this->envelopesApi;
    }

    public function getEnvelopeDefinition()
    {
        return $this->envelopeDefinition;
    }

    /**
     * Define o título do e-mail
     */
    public function setEmailSubject(string $emailSubject): void
    {
        $this->envelopeDefinition->setEmailSubject($emailSubject);
    }

    /**
     * Define o corpo do e-mail, quando não informado email_notification no DocuSign\eSign\Model\Signer
     */
    public function setEmailBlurb(string $emailBlurb):void
    {
        $this->envelopeDefinition->setEmailBlurb($emailBlurb);
    }

    /**
     * Define o ID da marca cadastrada na plataforma da docusign (Configurações > Marcas)
     */
    public function setBrandId(string $brandId)
    {
        $this->envelopeDefinition->setBrandId($brandId);
    }

    /**
     * Reenvia um envelope pelo ID informado
     *
     * @param string $idEnvelope
     */
    public function reenviar(string $idEnvelope): void
    {
        $options = new UpdateOptions();
        $options->setResendEnvelope('true');

        $envelope = new Envelope();
        $envelope->setEnvelopeId($idEnvelope);
        $this->envelopesApi->update(Agro_DocuSign_Auth::$docusignApiAccountId, $idEnvelope, $envelope, $options);
    }

    /**
     * Altera um signatário pelo recipient id informado nele anteriormente e envia um e-mail.
     *
     * @param string $idEnvelope
     * @param array $signersAlterados - Contém uma coleção de Signer
     */
    public function alterarSignatario(string $idEnvelope, array $signersAlterados): void
    {
        $recipients = new Recipients;
        $recipients->setSigners($signersAlterados);
        
        $this->envelopesApi->updateRecipients(Agro_DocuSign_Auth::$docusignApiAccountId, $idEnvelope, $recipients);
    }
}
