<?php

namespace App\Services;

use App\Models\NotificacaoCobrancaConfig;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;

class OnzFinanceService
{
    private $url_base;
    private $configId;
    private $client_id;
    private $client_secret;
    private $crt_onz;
    private $pfx_onz;
    private $key_onz;
    private $senha_onz;
    private $access_token;
    private $chave_pix;

    public function __construct($configId)
    {
        $this->url_base = env('ONZFINANCE_URL_BASE', 'https://api.pix.creditag.com.br');
        $this->configId = $configId;

        $config = NotificacaoCobrancaConfig::find($this->configId);
        $this->client_id = $config->client_id_onz;
        $this->client_secret = $config->client_secret_onz;
        $this->crt_onz = $config->crt_onz;
        $this->pfx_onz = $config->pfx_onz;
        $this->key_onz = $config->key_onz;
        $this->senha_onz = $config->senha_onz;
        $this->chave_pix = $config->chave_pix;

        if ($config->expires_in_onz && strtotime($config->expires_in_onz) > time()) {
            $this->access_token = $config->access_token_onz;
        } else {
            $this->access_token = null;
            $this->token();
        }
    }

    public function token()
    {
        try {
            $client = $this->guzzle();
            $body = [
                "client_id" => $this->client_id,
                "client_secret" => $this->client_secret,
                "grant_type" => 'client_credentials',
            ];

            $response = $client->post($this->url_base . '/oauth/token', [
                'json' => $body
            ]);

            $response = json_decode($response->getBody()->getContents(), true);
            if ($response['access_token'] ?? null) {
                $this->access_token = $response['access_token'];
                $config = NotificacaoCobrancaConfig::find($this->configId);
                $config->access_token_onz = $response['access_token'];
                $config->expires_in_onz = date('Y-m-d H:i:s', time() + $response['expires_in']);
                $config->save();
            }

            return json_decode($response->getBody()->getContents(), true);
        } catch (\Throwable $th) {
            return $this->handleException($th);
        }
    }

    public function gerarPix($data)
    {
        try {
            $client = $this->guzzle();
            $body = [
                "calendario" => [
                    "expiracao" => 86400, // dura 1 dia
                ],
                "devedor" => [
                    "nome" => $data['cliente'],
                ],
                "valor" => [
                    "original" => floatval($data['valor']),
                    "modalidadeAlteracao" => 1,
                ],
                "chave" => $this->chave_pix,
                "solicitacaoPagador" => $data['titulo'],
            ];

            $cpfCnpj = preg_replace('/\D/', '', $data['cpf_cnpj']);

            if (strlen($cpfCnpj) === 11) {
                $body['devedor']['cpf'] = $cpfCnpj;
            } elseif (strlen($cpfCnpj) === 14) {
                $body['devedor']['cnpj'] = $cpfCnpj;
            }

            $response = $client->post($this->url_base . '/cob', [
                'json' => $body
            ]);

            return json_decode($response->getBody()->getContents(), true);
        } catch (\Throwable $th) {
            return $this->handleException($th);
        }
    }

    public function guzzle()
    {
        $client = new Client([
            'cert' => [public_path($this->crt_onz), $this->senha_onz],
            'ssl_key' => [public_path($this->key_onz), $this->senha_onz],
            'pfx' => [public_path($this->pfx_onz), $this->senha_onz],
            'verify' => false,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->access_token,
                'Content-Type' => 'application/json',
            ]
        ]);

        return $client;
    }

    private function handleException($e)
    {
        try {
            if (@$e) {
                if (@$e instanceof \GuzzleHttp\Exception\RequestException) {
                    if ($e->hasResponse()) {
                        $responseBody = $e->getResponse()->getBody()->getContents();
                        Log::info("Service ONZ FINANCE ERROR: " . $responseBody);
                    } else {
                        Log::info("Service ONZ FINANCE ERROR: " . $e->getMessage());
                    }
                } else {
                    Log::info("Service ONZ FINANCE ERROR: " . $e->getMessage());
                }
            }
            return false;
        } catch (\Throwable $th) {
            Log::error("Service ONZ FINANCE handleException ERROR");
            return false;
        }
    }
}
