<?php

use App\Application\Services\Webhooks\WebhookDestinationValidator;
use App\Application\Services\Webhooks\WebhookRetryPolicy;
use App\Jobs\DeliverMerchantWebhookJob;
use App\Models\Merchant;
use App\Models\WebhookDelivery;
use App\Models\WebhookEndpoint;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

require __DIR__.'/../../vendor/autoload.php';

$app = require __DIR__.'/../../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();

$url = $argv[1] ?? null;
$merchantEmail = $argv[2] ?? 'ahmadshahzaib2490+3@gmail.com';

if (! $url) {
    fwrite(STDERR, "Usage: php storage/app/test_webhook_site_once.php <webhook-url> [merchant-email]\n");
    exit(1);
}

$merchant = Merchant::where('email', $merchantEmail)->first();

if (! $merchant) {
    fwrite(STDERR, "Merchant not found: {$merchantEmail}\n");
    exit(1);
}

$validator = app(WebhookDestinationValidator::class);
$probeStarted = microtime(true);

try {
    $ips = $validator->validate($url, false);
    $probe = Http::connectTimeout(5)
        ->timeout(15)
        ->withHeaders(['Content-Type' => 'application/json', 'X-Gateway-Probe' => 'true'])
        ->withBody(json_encode([
            'type' => 'webhook.probe',
            'created_at' => now()->utc()->toIso8601String(),
            'merchant_email' => $merchantEmail,
        ], JSON_UNESCAPED_SLASHES), 'application/json')
        ->post($url);

    $probeResult = [
        'reachable' => $probe->successful(),
        'status_code' => $probe->status(),
        'resolved_ips' => $ips,
        'duration_ms' => (int) round((microtime(true) - $probeStarted) * 1000),
    ];
} catch (Throwable $e) {
    $probeResult = [
        'reachable' => false,
        'error' => $e->getMessage(),
        'duration_ms' => (int) round((microtime(true) - $probeStarted) * 1000),
    ];
}

$endpoint = WebhookEndpoint::create([
    'merchant_id' => $merchant->id,
    'url' => $url,
    'secret_ciphertext' => 'whsec_'.Str::random(48),
    'events' => ['payment.*', 'payment.test', 'invoice.created'],
    'status' => 'active',
    'environment' => 'sandbox',
]);

$eventId = 'evt_'.Str::ulid();
$payload = [
    'id' => $eventId,
    'type' => 'payment.test',
    'created_at' => now()->utc()->toIso8601String(),
    'test_mode' => true,
    'data' => [
        'message' => 'Webhook.site signed delivery test',
        'merchant_email' => $merchantEmail,
    ],
];

$raw = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);

$delivery = WebhookDelivery::create([
    'event_id' => $eventId,
    'endpoint_id' => $endpoint->id,
    'payload' => $payload,
    'raw_payload' => $raw,
    'attempt_count' => 0,
    'status' => 'queued',
    'next_attempt_at' => now(),
]);

app(DeliverMerchantWebhookJob::class, ['deliveryId' => $delivery->id])
    ->handle(app(WebhookRetryPolicy::class), $validator);

$delivery->refresh();

$result = [
    'merchant_email' => $merchantEmail,
    'webhook_url' => $url,
    'webhook_site_inbox' => str_replace('https://webhook.site/', 'https://webhook.site/#!/view/', $url),
    'probe' => $probeResult,
    'endpoint' => [
        'id' => $endpoint->id,
        'status' => $endpoint->status,
        'environment' => $endpoint->environment,
        'events' => $endpoint->events,
    ],
    'delivery' => [
        'id' => $delivery->id,
        'event_id' => $delivery->event_id,
        'status' => $delivery->status,
        'attempt_count' => $delivery->attempt_count,
        'last_response_code' => $delivery->last_response_code,
        'last_error' => $delivery->last_error,
        'delivered_at' => optional($delivery->delivered_at)->toIso8601String(),
    ],
];

echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES).PHP_EOL;
