<?php

declare(strict_types=1);

namespace App\Jobs\Paynl;

use App\Enums\TaxCode;
use App\Models\Merchant;
use App\Models\MerchantPaymentMethod;
use App\Services\PaynlService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Arr;
use Paynl\Error\Api;
use Paynl\Error\Error;
use Paynl\Error\Required\ApiToken;

final class FetchEnabledPaymentMethodForMerchant implements ShouldQueue
{
    use Dispatchable;
    use Queueable;
    use InteractsWithQueue;
    use SerializesModels;

    public function __construct(
        protected array $merchant
    ) {
    }

    public function handle(PaynlService $paynlService): void
    {
        $services = Arr::get($this->merchant, 'services');

        $merchantModel = Merchant::query()
            ->updateOrCreate(
                attributes: [
                    'pay_id' => $this->merchant['merchantId'],
                ],
                values: [
                    'pay_id' => Arr::get($this->merchant, 'merchantId'),
                    'name' => Arr::get($this->merchant, 'merchantName'),
                    'payout_interval' => Arr::get($this->merchant, 'payoutInterval'),
                    'services' => Arr::get($this->merchant, 'services'),
                    'contract_package' => Arr::get($this->merchant, 'packageType'),
                    'tax_code' => TaxCode::HOOG_VERK_21,
                ]
            );

        if (empty($services)) {
            return;
        }

        foreach ($services as $service) {
            try {
                foreach ($paynlService->paymentMethods($service['serviceId']) as $paymentMethod) {
                    $paymentMethodName = strtolower($paymentMethod['name']);

                    $merchantModel->paymentMethods()->firstOrCreate(
                        attributes: [
                            'payment_method_id' => $paymentMethod['id'],
                            'merchant_id' => $merchantModel->id,
                        ],
                        values: [
                            'code' => MerchantPaymentMethod::DEFAULT_CODES[$paymentMethodName] ?? null,
                            'payment_method_name' => $paymentMethodName,
                            'fee' => MerchantPaymentMethod::DEFAULT_FEES[$paymentMethodName] ?? 0.00,
                            'provision' => MerchantPaymentMethod::DEFAULT_PROVISION[$paymentMethodName] ?? null,
                        ]
                    );
                }

                $merchantModel->push();
            } catch (Api|ApiToken|Error $exception) {
                $this->fail($exception);
            }
        }
    }
}
