<?php

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

/**
 * What a renewal's invoice hangs off, since a renewal has no order.
 *
 * An Order is a thing somebody bought: it is created at a checkout, it sits in
 * a cart, it is consumed by provisioning or by a plan change. A month rolling
 * over is none of that — nobody ordered it, and manufacturing an Order to
 * squeeze a renewal through IssueInvoice::forOrders() would put a purchase in
 * the shop's own records that no customer ever made. So the document points at
 * the CONTRACT it billed instead, and `order_id` stays null for it.
 *
 * `stripe_invoice_id` is what makes issuing idempotent. Stripe retries a webhook
 * until it gets a 2xx and delivers the same invoice to several endpoints, so
 * "already issued" is the ordinary case — and an invoice number, once handed
 * out, can never be handed out again. Unique in the database rather than checked
 * in PHP, because two deliveries arriving together would both pass a check.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::table('invoices', function (Blueprint $table) {
            $table->foreignId('subscription_id')->nullable()->after('order_id')
                ->constrained()->nullOnDelete();

            $table->string('stripe_invoice_id')->nullable()->unique()->after('subscription_id');
        });
    }

    public function down(): void
    {
        Schema::table('invoices', function (Blueprint $table) {
            $table->dropUnique(['stripe_invoice_id']);
            $table->dropColumn('stripe_invoice_id');
            $table->dropConstrainedForeignId('subscription_id');
        });
    }
};
