<?php

namespace Daniv04\HaciendaPackage\Jobs;

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;
use Daniv04\HaciendaPackage\Models\SentReceipt;
use Daniv04\HaciendaPackage\Services\Providers\ProviderFactoryService;

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

    public $tries = 3;
    public $timeout = 120; // Job timeout in seconds
    public $backoff = [30, 60, 90]; 

    /**
     * Create a new job instance.
     */
    public function __construct(
        public SentReceipt $receipt,
        public array $validatedData,
        public string $provider
    ){}

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(ProviderFactoryService $providerFactoryService): void
    {
        Log::info("Starting SendSentReceiptToProviderJob for SentReceipt",[
            'receipt_id' => $this->receipt->id,
            'provider' => $this->provider
        ]);

        try{

            $providerInstance = $providerFactoryService->getProviderInstance($this->provider);
            if (!$providerInstance) {
                Log::error("Provider instance not found in SendSentReceiptToProviderJob",[
                    'receipt_id' => $this->receipt->id,
                    'provider' => $this->provider
                ]);
                return;
            }

            //Send document
            $response = $providerInstance->sendDocument($this->validatedData, $this->receipt->consecutive_number);

            if($response['success'] == false)
                {
                    Log::error("Error sending document to provider in SendSentReceiptToProviderJob",[
                        'receipt_id' => $this->receipt->id,
                        'provider' => $this->provider,
                        'error' => $response['message'],
                        'response' => $response
                    ]);
                    throw new \Exception("Error sending document to provider: " . $response['message']);
                } 
            
            // Update receipt with provider response data if succesfull
            $this->receipt->update([
                'receipt_status' => 'sent',
                'ui_key' => $response['data']['clave'],
                'sent_to_hacienda_at' => $response['data']['fecha'],
                'signed_xml' => $response['data']['data'] ?? null,
            ]);

            Log::info("Successfully sent document to provider in SendSentReceiptToProviderJob",[
                'receipt_id' => $this->receipt->id,
                'ui_key' => $this->receipt->ui_key,
                'provider' => $this->provider,
                'response' => $response
            ]);

        } catch (\Exception $e) {
            Log::error('Error in SendSentReceiptToProviderJob', [
                'receipt_id' => $this->receipt->id,
                'attempt' => $this->attempts(),
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            throw $e;
        }
    }

    public function failed(\Throwable $exception): void
    {
        Log::error('SendReceiptToProviderJob failed after maximum attempts', [
            'receipt_id' => $this->receipt->id,
            'attempts' => $this->attempts(),
            'error' => $exception->getMessage(),
            'trace' => $exception->getTraceAsString()
        ]);

        $this->receipt->update([
            'receipt_status' => 'failed',
        ]);
    }
}