<?php

namespace App\Services\Pagarme;

use App\Data\Pagarme\Request\CardRequestData\CardBillingAddressData;
use App\Data\Pagarme\Request\CardRequestData\CardRequestData;
use App\Data\Pagarme\Response\CardResponseData;
use App\Models\Address;
use App\Models\ClientPaymentMethod;
use App\Services\Pagarme\Concerns\SendsPagarmeRequests;

class PagarmeCardService
{
    use SendsPagarmeRequests;

    public function __construct(
        private readonly PagarmeCustomerService $pagarmeCustomerService,
    ) {}

    public function createCardForPaymentMethod(ClientPaymentMethod $paymentMethod): ?string
    {
        if (! empty($paymentMethod->gateway_card_id)) {
            return $paymentMethod->gateway_card_id;
        }

        $paymentMethod->loadMissing('client.user');

        $customerId = $this->pagarmeCustomerService->createCustomerForClient(
            $paymentMethod->client,
            []
        );

        $cardData = CardResponseData::fromArray($this->pagarmeRequest(
            method: 'POST',
            path: "/customers/{$customerId}/cards",

            payload: new CardRequestData(
                token: $paymentMethod->token,
                label: $paymentMethod->card_name,
                billingAddress: CardBillingAddressData::fromAddress(
                    Address::query()
                        ->with(['city.state', 'state'])
                        ->where('source', 'client')
                        ->where('source_id', $paymentMethod->client_id)
                        ->orderByDesc('is_primary')
                        ->latest('id')
                        ->first()
                ),
            ),

            idempotencyKey: $this->idempotencyKey($paymentMethod),
            errorMessage: 'Erro ao salvar cartao no Pagar.me.',
        ));

        $cardId = $cardData->requireId();

        $paymentMethod->forceFill([
            'gateway_card_id'  => $cardId,
            'brand'            => $paymentMethod->brand ?: $cardData->brand,
            'last_four_digits' => $paymentMethod->last_four_digits ?: $cardData->lastFourDigits,
        ])->save();

        return $cardId;
    }

    // evita criacao duplicada de cartao

    private function idempotencyKey(ClientPaymentMethod $paymentMethod): string
    {
        return "client-payment-method-{$paymentMethod->id}-card";
    }
}
