<?php

namespace App\Services;

use Illuminate\Support\Str;
use MercadoPago\Client\Payment\PaymentClient;
use MercadoPago\Client\Common\RequestOptions;
use MercadoPago\Exceptions\MPApiException;
use MercadoPago\MercadoPagoConfig;

class MercadoPagoService
{
    public function __construct()
    {
        MercadoPagoConfig::setAccessToken(config('services.mercadopago.access_token'));

        // em desenvolvimento local, descomente:
        // MercadoPagoConfig::setRuntimeEnviroment(MercadoPagoConfig::LOCAL);
    }

    /**
     * Cria um pagamento PIX e retorna QR + copia-e-cola.
     */
    public function createPix(array $data): array
    {
        $client = new PaymentClient();
        $options = $this->requestOptions();

        // expiração: 30 minutos
        $expiresAt = now()->addMinutes(30);

        try {
            $payment = $client->create([
                'transaction_amount'   => (float) $data['amount'],
                'payment_method_id'    => 'pix',
                'description'          => 'Recarga de saldo - Venchile',
                'external_reference'   => $data['external_reference'] ?? Str::uuid()->toString(),
                'date_of_expiration'   => $expiresAt->format('Y-m-d\TH:i:s.vP'),
                'notification_url'     => config('services.mercadopago.webhook_url'),
                'payer' => [
                    'email'      => $data['payer']['email'],
                    'first_name' => $data['payer']['first_name'] ?? null,
                    'last_name'  => $data['payer']['last_name'] ?? null,
                    'identification' => isset($data['payer']['document'])
                        ? [
                            'type'   => $data['payer']['document']['type'],   // CPF | CNPJ
                            'number' => $data['payer']['document']['number'],
                        ]
                        : null,
                ],
            ], $options);

            $tx = $payment->point_of_interaction->transaction_data ?? null;

            return [
                'id'              => $payment->id,
                'status'          => $payment->status,
                'qr_code'         => $tx->qr_code         ?? null,   // copia-e-cola
                'qr_code_base64'  => $tx->qr_code_base64  ?? null,   // imagem PNG
                'ticket_url'      => $tx->ticket_url      ?? null,
                'expires_at'      => $expiresAt->toIso8601String(),
            ];
        } catch (MPApiException $e) {
            throw new \RuntimeException(
                'MP error: ' . $e->getApiResponse()->getContent()['message'] ?? $e->getMessage()
            );
        }
    }

    /**
     * Cria um pagamento com cartão a partir do token gerado no frontend.
     */
    public function createCardPayment(array $data): array
    {
        $client = new PaymentClient();
        $options = $this->requestOptions();

        try {
            $payment = $client->create([
                'transaction_amount' => (float) $data['amount'],
                'token'              => $data['token'],
                'description'        => 'Recarga de saldo - Venchile',
                'installments'       => (int) ($data['installments'] ?? 1),
                'payment_method_id'  => $data['payment_method_id'],
                'issuer_id'          => isset($data['issuer_id']) ? (string) $data['issuer_id'] : null,
                'external_reference' => $data['external_reference'] ?? Str::uuid()->toString(),
                'notification_url'   => config('services.mercadopago.webhook_url'),
                'payer' => [
                    'email' => $data['payer']['email'],
                    'identification' => [
                        'type'   => $data['payer']['document']['type'],
                        'number' => $data['payer']['document']['number'],
                    ],
                ],
            ], $options);

            return [
                'id'                 => $payment->id,
                'status'             => $payment->status,         // approved | pending | rejected
                'status_detail'      => $payment->status_detail,
                'payment_method'     => $payment->payment_method_id,
                'installments'       => $payment->installments,
                'transaction_amount' => $payment->transaction_amount,
            ];
        } catch (MPApiException $e) {
            $msg = $e->getApiResponse()->getContent()['message'] ?? $e->getMessage();
            throw new \RuntimeException("MP error: {$msg}");
        }
    }

    /**
     * Consulta status atual de um pagamento.
     */
    public function getPayment(string|int $id): array
    {
        $client = new PaymentClient();

        try {
            $payment = $client->get($id);

            return [
                'id'                 => $payment->id,
                'status'             => $payment->status,
                'status_detail'      => $payment->status_detail,
                'transaction_amount' => $payment->transaction_amount,
                'payment_method'     => $payment->payment_method_id,
                'external_reference' => $payment->external_reference,
                'date_approved'      => $payment->date_approved,
            ];
        } catch (MPApiException $e) {
            throw new \RuntimeException('MP error: ' . $e->getMessage());
        }
    }

    private function requestOptions(): RequestOptions
    {
        $opts = new RequestOptions();
        $opts->setCustomHeaders(['X-Idempotency-Key: ' . Str::uuid()->toString()]);
        return $opts;
    }
}
