<?php

namespace App\Modules\Transactions\Jobs;

use App\Models\Transaction;
use App\Modules\ProviderIntegration\Interfaces\ProviderInterface;
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\Facades\Log;

class QueryTransactionStatus implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $timeout = 30;

    public function __construct(
        public string $reference
    ) {}

    public function handle(ProviderInterface $provider): void
    {
        $transaction = Transaction::where('reference', $this->reference)->first();

        if (!$transaction || $transaction->status !== 'processing') {
            return;
        }

        if (!$transaction->provider_reference) {
            return;
        }

        try {
            $response = $provider->queryTransactionStatus($transaction->provider_reference);

            if (isset($response['code']) && $response['code'] === '000') {
                $transaction->update([
                    'status' => 'successful',
                    'provider_response' => $response,
                    'completed_at' => now(),
                ]);
            } elseif (isset($response['code']) && in_array($response['code'], ['014', '013'])) {
                if ($this->attempts() < $this->tries) {
                    $this->release(now()->addMinutes(5));
                } else {
                    $transaction->update([
                        'status' => 'timeout',
                        'failure_reason' => 'Transaction timed out after multiple queries',
                        'completed_at' => now(),
                    ]);
                }
            } else {
                $transaction->update([
                    'status' => 'failed',
                    'failure_reason' => $response['response_description'] ?? 'Transaction failed',
                    'provider_response' => $response,
                    'completed_at' => now(),
                ]);
            }
        } catch (\Exception $e) {
            Log::error('Transaction query failed', ['reference' => $this->reference, 'error' => $e->getMessage()]);
        }
    }
}
