<?php

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

return new class extends Migration
{
    public function up(): void
    {
        if (! Schema::hasTable('order_receipts')) {
            Schema::create('order_receipts', function (Blueprint $table) {
                $table->id();
                $table->string('voucher_no', 60)->nullable()->unique();
                $table->uuid('idempotency_key')->unique();
                $table->foreignId('order_id')->constrained()->cascadeOnDelete();
                $table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete();
                $table->decimal('amount', 24, 3);
                $table->string('payment_method', 100);
                $table->string('transaction_ref', 120)->nullable();
                $table->string('account_type', 80)->default('customer_advance_liability');
                $table->string('receipt_status', 30)->default('posted');
                $table->timestamp('received_at');
                $table->text('notes')->nullable();
                $table->foreignId('created_by_admin_id')->nullable()->constrained('admins')->nullOnDelete();
                $table->foreignId('voided_by_admin_id')->nullable()->constrained('admins')->nullOnDelete();
                $table->timestamp('voided_at')->nullable();
                $table->timestamps();

                $table->unique(['order_id', 'transaction_ref'], 'order_receipts_order_transaction_unique');
                $table->index(['order_id', 'receipt_status']);
            });
        } else {
            Schema::table('order_receipts', function (Blueprint $table) {
                if (! Schema::hasColumn('order_receipts', 'voucher_no')) {
                    $table->string('voucher_no', 60)->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'idempotency_key')) {
                    $table->uuid('idempotency_key')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'order_id')) {
                    $table->unsignedBigInteger('order_id')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'amount')) {
                    $table->decimal('amount', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_receipts', 'payment_method')) {
                    $table->string('payment_method', 100)->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'transaction_ref')) {
                    $table->string('transaction_ref', 120)->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'account_type')) {
                    $table->string('account_type', 80)->default('customer_advance_liability');
                }
                if (! Schema::hasColumn('order_receipts', 'receipt_status')) {
                    $table->string('receipt_status', 30)->default('posted');
                }
                if (! Schema::hasColumn('order_receipts', 'received_at')) {
                    $table->timestamp('received_at')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'notes')) {
                    $table->text('notes')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'created_by_admin_id')) {
                    $table->unsignedBigInteger('created_by_admin_id')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'voided_by_admin_id')) {
                    $table->unsignedBigInteger('voided_by_admin_id')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'voided_at')) {
                    $table->timestamp('voided_at')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'created_at')) {
                    $table->timestamp('created_at')->nullable();
                }
                if (! Schema::hasColumn('order_receipts', 'updated_at')) {
                    $table->timestamp('updated_at')->nullable();
                }
            });
        }

        if (Schema::hasTable('order_payments') && ! Schema::hasColumn('order_payments', 'order_receipt_id')) {
            Schema::table('order_payments', function (Blueprint $table) {
                $table->unsignedBigInteger('order_receipt_id')->nullable()->after('order_id');
                $table->index('order_receipt_id', 'order_payments_receipt_id_index');
            });
        }

        if (! Schema::hasTable('order_exchanges')) {
            Schema::create('order_exchanges', function (Blueprint $table) {
                $table->id();
                $table->string('exchange_no', 60)->nullable()->unique();
                $table->uuid('idempotency_key')->unique();
                $table->foreignId('order_id')->constrained()->cascadeOnDelete();
                $table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete();
                $table->decimal('returned_amount', 24, 3)->default(0);
                $table->decimal('replacement_amount', 24, 3)->default(0);
                $table->decimal('difference_amount', 24, 3)->default(0);
                $table->boolean('affects_collectable')->default(true);
                $table->string('exchange_status', 30)->default('posted');
                $table->timestamp('exchanged_at');
                $table->text('notes')->nullable();
                $table->foreignId('created_by_admin_id')->nullable()->constrained('admins')->nullOnDelete();
                $table->foreignId('voided_by_admin_id')->nullable()->constrained('admins')->nullOnDelete();
                $table->timestamp('voided_at')->nullable();
                $table->timestamps();

                $table->index(['order_id', 'exchange_status']);
            });
        } else {
            Schema::table('order_exchanges', function (Blueprint $table) {
                if (! Schema::hasColumn('order_exchanges', 'exchange_no')) {
                    $table->string('exchange_no', 60)->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'idempotency_key')) {
                    $table->uuid('idempotency_key')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'order_id')) {
                    $table->unsignedBigInteger('order_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'user_id')) {
                    $table->unsignedBigInteger('user_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'returned_amount')) {
                    $table->decimal('returned_amount', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_exchanges', 'replacement_amount')) {
                    $table->decimal('replacement_amount', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_exchanges', 'difference_amount')) {
                    $table->decimal('difference_amount', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_exchanges', 'affects_collectable')) {
                    $table->boolean('affects_collectable')->default(true);
                }
                if (! Schema::hasColumn('order_exchanges', 'exchange_status')) {
                    $table->string('exchange_status', 30)->default('posted');
                }
                if (! Schema::hasColumn('order_exchanges', 'exchanged_at')) {
                    $table->timestamp('exchanged_at')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'notes')) {
                    $table->text('notes')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'created_by_admin_id')) {
                    $table->unsignedBigInteger('created_by_admin_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'voided_by_admin_id')) {
                    $table->unsignedBigInteger('voided_by_admin_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'voided_at')) {
                    $table->timestamp('voided_at')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'created_at')) {
                    $table->timestamp('created_at')->nullable();
                }
                if (! Schema::hasColumn('order_exchanges', 'updated_at')) {
                    $table->timestamp('updated_at')->nullable();
                }
            });
        }

        if (! Schema::hasTable('order_exchange_items')) {
            Schema::create('order_exchange_items', function (Blueprint $table) {
                $table->id();
                $table->foreignId('order_exchange_id')->constrained('order_exchanges')->cascadeOnDelete();
                $table->string('direction', 20);
                $table->foreignId('order_detail_id')->nullable()->constrained('order_details')->nullOnDelete();
                $table->foreignId('item_id')->nullable()->constrained('items')->nullOnDelete();
                $table->string('item_name');
                $table->text('variation')->nullable();
                $table->unsignedInteger('quantity');
                $table->decimal('unit_price', 24, 3);
                $table->decimal('line_total', 24, 3);
                $table->timestamps();

                $table->index(['order_exchange_id', 'direction']);
            });
        } else {
            Schema::table('order_exchange_items', function (Blueprint $table) {
                if (! Schema::hasColumn('order_exchange_items', 'order_exchange_id')) {
                    $table->unsignedBigInteger('order_exchange_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'direction')) {
                    $table->string('direction', 20)->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'order_detail_id')) {
                    $table->unsignedBigInteger('order_detail_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'item_id')) {
                    $table->unsignedBigInteger('item_id')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'item_name')) {
                    $table->string('item_name')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'variation')) {
                    $table->text('variation')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'quantity')) {
                    $table->unsignedInteger('quantity')->default(0);
                }
                if (! Schema::hasColumn('order_exchange_items', 'unit_price')) {
                    $table->decimal('unit_price', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_exchange_items', 'line_total')) {
                    $table->decimal('line_total', 24, 3)->default(0);
                }
                if (! Schema::hasColumn('order_exchange_items', 'created_at')) {
                    $table->timestamp('created_at')->nullable();
                }
                if (! Schema::hasColumn('order_exchange_items', 'updated_at')) {
                    $table->timestamp('updated_at')->nullable();
                }
            });
        }
    }

    public function down(): void
    {
        // Intentionally non-destructive: this migration may run on live data.
    }
};
