<?php

namespace App\Jobs;

use App\Models\Booking;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * INT-03: fires whenever a booking's status changes (see BookingObserver),
 * so a corporate Account's own systems can react without polling. Signed
 * the same way this app already verifies inbound Stripe webhooks — an
 * HMAC-SHA256 over the raw JSON body, in an X-Webhook-Signature header —
 * so the receiving end can trust the payload actually came from here.
 */
class SendOutboundWebhook implements ShouldQueue
{
    use Queueable;

    public int $tries = 3;

    public array $backoff = [10, 60, 300];

    public function __construct(private readonly int $bookingId) {}

    public function handle(): void
    {
        $booking = Booking::with(['company', 'customer', 'driver', 'status'])->find($this->bookingId);

        if (! $booking || ! $booking->company?->hasWebhookConfigured()) {
            return;
        }

        $company = $booking->company;

        $payload = [
            'event' => 'booking.status_changed',
            'sent_at' => now()->toIso8601String(),
            'booking' => [
                'id' => $booking->id,
                'booking_number' => $booking->booking_number,
                'status' => $booking->status->name ?? null,
                'customer_name' => $booking->customer?->name,
                'driver_name' => $booking->driver?->full_name,
                'pickup_address' => $booking->pickup_address,
                'dropoff_address' => $booking->dropoff_address,
                'pickup_datetime' => $booking->pickup_datetime?->toIso8601String(),
                'fare_amount' => (float) $booking->fare_amount,
                'account_id' => $booking->account_id,
            ],
        ];

        $body = json_encode($payload);
        $signature = hash_hmac('sha256', $body, $company->webhook_secret);

        $response = Http::withBody($body, 'application/json')
            ->withHeaders(['X-Webhook-Signature' => $signature])
            ->timeout(5)
            ->post($company->webhook_url);

        if (! $response->successful()) {
            Log::warning('SendOutboundWebhook: delivery failed.', [
                'company_id' => $company->id,
                'booking_id' => $booking->id,
                'status' => $response->status(),
            ]);
        }
    }
}
