Source path: app/Services/Ai/Video/FalVideo.php
Extracted from supplied specification. Review before copying into application.

<?php
namespace App\Services\Ai\Video;

use App\Services\Ai\VideoProvider;
use Illuminate\Support\Facades\Http;

class FalVideo implements VideoProvider
{
    public function configured(array $c): bool { return !empty($c['api_key']) && !empty($c['model']); }

    public function submit(string $prompt, array $opts, array $c): array
    {
        $res = Http::withHeaders(['Authorization' => 'Key ' . $c['api_key']])
            ->post("https://queue.fal.run/{$c['model']}", [
                'prompt' => $prompt,
                'aspect_ratio' => $opts['aspect'] ?? '9:16',
            ])->throw();

        return [
            'request_id'   => $res->json('request_id'),
            'status_url'   => $res->json('status_url'),
            'response_url' => $res->json('response_url'),
        ];
    }

    public function poll(array $meta, array $c): array
    {
        $h = ['Authorization' => 'Key ' . $c['api_key']];
        $status = Http::withHeaders($h)->get($meta['status_url'])->throw()->json('status');

        if (in_array($status, ['IN_QUEUE', 'IN_PROGRESS'])) return ['status' => 'processing'];
        if ($status !== 'COMPLETED') return ['status' => 'failed', 'error' => (string) $status];

        $out = Http::withHeaders($h)->get($meta['response_url'])->throw()->json();
        $url = $out['video']['url'] ?? $out['data']['video']['url'] ?? null;
        return $url ? ['status' => 'succeeded', 'url' => $url] : ['status' => 'failed', 'error' => 'No video URL in result.'];
    }
}
