<?php

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

/**
 * Subscription lifecycle: subscription -> invoice -> manual payment proof.
 *
 * Payments in the Pakistani market are collected out-of-band (Easypaisa,
 * JazzCash, bank transfer). The tenant uploads a screenshot, an admin
 * verifies it, and only then does the subscription become active.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('subscriptions', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('saas_product_id')->constrained()->cascadeOnDelete();
            $table->foreignId('plan_id')->constrained()->restrictOnDelete();

            $table->string('billing_cycle', 20)->default('monthly');
            $table->string('status', 30)->default('trial');

            $table->decimal('amount', 12, 2)->default(0)->comment('Price agreed for this term');
            $table->string('currency', 3)->default('PKR');

            $table->timestamp('starts_at')->nullable();
            $table->timestamp('ends_at')->nullable();
            $table->timestamp('grace_ends_at')->nullable();
            $table->timestamp('cancelled_at')->nullable();
            $table->text('cancellation_reason')->nullable();

            $table->boolean('is_trial')->default(false);
            $table->boolean('auto_renew')->default(true);

            /*
             * Snapshot of the plan's features / limits at purchase time so that
             * changing a plan later never silently downgrades a paying tenant.
             */
            $table->json('features_snapshot')->nullable();
            $table->json('limits_snapshot')->nullable();

            $table->foreignId('previous_subscription_id')->nullable()
                ->constrained('subscriptions')->nullOnDelete();
            $table->text('admin_notes')->nullable();
            $table->timestamps();

            $table->index(['tenant_id', 'status']);
            $table->index(['saas_product_id', 'status']);
            $table->index('ends_at');
        });

        Schema::create('subscription_invoices', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('subscription_id')->constrained()->cascadeOnDelete();

            $table->string('invoice_number')->unique();
            $table->string('status', 30)->default('unpaid');

            $table->decimal('subtotal', 12, 2)->default(0);
            $table->decimal('discount', 12, 2)->default(0);
            $table->decimal('tax', 12, 2)->default(0);
            $table->decimal('total', 12, 2)->default(0);
            $table->decimal('paid_amount', 12, 2)->default(0);
            $table->string('currency', 3)->default('PKR');

            $table->date('issued_on');
            $table->date('due_on')->nullable();
            $table->date('period_start')->nullable();
            $table->date('period_end')->nullable();
            $table->timestamp('paid_at')->nullable();

            $table->text('notes')->nullable();
            $table->timestamps();

            $table->index(['tenant_id', 'status']);
            $table->index('due_on');
        });

        Schema::create('subscription_payments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('subscription_id')->constrained()->cascadeOnDelete();
            $table->foreignId('subscription_invoice_id')->nullable()
                ->constrained()->nullOnDelete();
            $table->foreignId('payment_account_id')->nullable()
                ->constrained()->nullOnDelete()
                ->comment('Which of our accounts the tenant claims to have paid into');

            $table->string('reference')->unique();
            $table->string('gateway', 30)->comment('easypaisa | jazzcash | bank_transfer');
            $table->decimal('amount', 12, 2);
            $table->string('currency', 3)->default('PKR');

            // What the tenant tells us about the transfer.
            $table->string('sender_name')->nullable();
            $table->string('sender_account')->nullable();
            $table->string('transaction_id')->nullable();
            $table->timestamp('paid_at')->nullable();
            $table->string('proof_path')->nullable()->comment('Uploaded screenshot / receipt');
            $table->text('tenant_note')->nullable();

            // What we decide about it.
            $table->string('status', 20)->default('pending');
            $table->unsignedBigInteger('reviewed_by')->nullable()->comment('users.id in this panel');
            $table->timestamp('reviewed_at')->nullable();
            $table->text('rejection_reason')->nullable();
            $table->text('admin_note')->nullable();

            $table->string('submitted_ip', 45)->nullable();
            $table->timestamps();

            $table->index(['status', 'created_at']);
            $table->index(['tenant_id', 'status']);
            $table->index('transaction_id');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('subscription_payments');
        Schema::dropIfExists('subscription_invoices');
        Schema::dropIfExists('subscriptions');
    }
};
