<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('payments', function (Blueprint $table) {
            // Where to send the customer to pay, and when that link dies.
            $table->string('checkout_url', 1024)->nullable()->after('external_ref');
            $table->dateTime('expires_at')->nullable()->after('checkout_url');

            // Proof of a manual transfer. Stored on an external disk, so only
            // the pointer lives here.
            $table->string('proof_disk', 40)->nullable();
            $table->string('proof_path')->nullable();
            $table->dateTime('proof_uploaded_at')->nullable();

            // Set when money landed for a booking that had already lost its
            // slot. Nobody is at fault and the studio owes a refund, so it
            // must be impossible to miss rather than buried in a log.
            $table->boolean('needs_manual_refund')->default(false);
        });

        /*
         * Every webhook Revolut sends us, recorded before it is acted on.
         *
         * The unique event_id is the idempotency guarantee. Revolut retries
         * on any non-2xx, and retries are not rare — a slow response or a
         * deploy mid-delivery is enough. Without this, a retried
         * ORDER_COMPLETED would confirm the same booking twice and write a
         * second payment row, quietly doubling the day's takings.
         */
        Schema::create('webhook_events', function (Blueprint $table) {
            $table->id();
            $table->string('source', 30)->default('revolut');
            $table->string('event_id')->unique();
            $table->string('event_type', 60);
            $table->string('external_ref')->nullable();
            $table->json('payload');

            $table->dateTime('received_at');
            $table->dateTime('processed_at')->nullable();
            $table->string('status', 20)->default('received');
            $table->text('error')->nullable();

            $table->index(['status', 'received_at']);
            $table->index('external_ref');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('webhook_events');

        Schema::table('payments', function (Blueprint $table) {
            $table->dropColumn([
                'checkout_url', 'expires_at', 'proof_disk', 'proof_path',
                'proof_uploaded_at', 'needs_manual_refund',
            ]);
        });
    }
};
