<?php

namespace App\Modules\FactReceipt\Infraestructure;

use App\Modules\Credential\Domain\CredentialList;
use App\Modules\ExternalApiRequest\Application\Create\CreateExternalApiRequestQuery;
use App\Modules\ExternalApiRequest\Application\Create\CreateExternalApiRequestResponse;
use App\Modules\ExternalApiRequest\Application\Update\UpdateExternalApiRequestQuery;
use App\Modules\ExternalApiRequest\Domain\ExternalApiRequest;
use App\Modules\ExternalApiRequest\Domain\ExternalApiRequestStatus;
use App\Modules\FactReceipt\Domain\DTODatosComprobante;
use App\Modules\FactReceipt\Domain\DtoFactReceiptRepository;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;

class YachayFactReceiptRepository implements DtoFactReceiptRepository
{

    public function __construct(
        private QueryBus $queryBus
    ) {
    }

    private static $api = 'https://iisrestfacturascore.azurewebsites.net/';
    private static $endpoint = 'api/generar-comprobante-venta/factura-boleta-movil/';

    public function create(DTODatosComprobante $model, CredentialList $credentialList)
    {
        $id = $credentialList->getValue('Billing_Url_Id');
        $idUser = $credentialList->getValue('Billing_Url_IdUser');
        $idEmpresa = $credentialList->getValue('Billing_Header_IdEmpresa');
        $auth = $credentialList->getValue('Billing_Header_Authorization');

        $url = self::$api . self::$endpoint . $id . '/' . $idUser;
        try {
            $container = [];
            $history = Middleware::history($container);
            $stack = HandlerStack::create();
            $stack->push($history);
            $client = new Client(['handler' => $stack]);

            /** @var CreateExternalApiRequestResponse $response */
            $response = $this->queryBus->ask(new CreateExternalApiRequestQuery(
                date('Y-m-d H:i:s'),
                $url,
                'POST',
                json_encode($model->toJSON()),
                '',
                ExternalApiRequestStatus::PENDING
            ));

            $idEAR = $response->response();

            $res = $client->request(
                'POST',
                $url,
                [
                    'json' => $model->toJSON(),
                    'headers' => [
                        'Cache-Control' => 'no-cache',
                        'Content-Type' => 'application/json',
                        'User-Agent' => 'PostmanRuntime/7.37.3',
                        'Accept-Encoding' => 'gzip, deflate, br',
                        'Connection' => 'keep-alive',
                        'IdEmpresa' => $idEmpresa,
                        'Authorization' => $auth,
                        'Accept' => 'application/json, application/octet-stream',
                    ]
                ]
            );
            $this->queryBus->ask(new UpdateExternalApiRequestQuery($idEAR, '__OK__', ExternalApiRequestStatus::SUCCESS));

            return $res->getBody()->__toString();
        } catch (ClientException $e) {
            $this->queryBus->ask(new UpdateExternalApiRequestQuery($idEAR, $e->getMessage(), ExternalApiRequestStatus::ERROR));
            new BadRequestException($e->getMessage());
        } catch (ServerException $e) {
            $body = $e->getResponse()->getBody()->__toString();
            $this->queryBus->ask(new UpdateExternalApiRequestQuery($idEAR, $body, ExternalApiRequestStatus::ERROR));
            throw $e;
        }
    }
}
