<?php

namespace App\Jobs;

use App\VirtualTryonResult;
use App\Services\FaceSwapManager;
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 ProcessVirtualTryon implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $tryonResult;

    /**
     * The number of seconds the job can run before timing out.
     * Must be greater than the driver timeout + retry overhead so
     * the worker does not kill the job while the API call is pending.
     */
    public $timeout = 300;

    /**
     * The number of times the job may be attempted.
     */
    public $tries = 2;

    /**
     * Backoff between retries (seconds).
     */
    public $backoff = [30, 120];

    public function __construct(VirtualTryonResult $tryonResult)
    {
        $this->onQueue(config('queue.connections.redis.queue'));
        $this->tryonResult = $tryonResult;
    }

    public function handle(FaceSwapManager $service)
    {
        $service->swap($this->tryonResult);
    }

    public function failed(\Throwable $exception)
    {
        $payload = [
            'result_id' => $this->tryonResult->id ?? null,
            'code' => $this->tryonResult->code ?? null,
            'error' => $exception->getMessage(),
        ];
        if (app()->environment(['local', 'testing'])) {
            $payload['trace'] = $exception->getTraceAsString();
        }
        Log::error('ProcessVirtualTryon job failed', $payload);

        if ($this->tryonResult) {
            // Never persist the raw exception message — it may contain payload data
            // or API response fragments. Keep a generic marker; details are in logs.
            $this->tryonResult->update([
                'status' => 'failed',
                'error' => 'Processing failed',
            ]);
        }
    }
}
