<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Check if payments table already exists and modify or create accordingly
        if (!Schema::hasTable('payments')) {
            Schema::create('payments', function (Blueprint $table) {
                $table->id();
                $table->foreignId('user_id')->constrained()->onDelete('cascade');
                $table->string('tracking_code')->unique();
                $table->string('authority')->nullable();
                $table->string('reference_id')->nullable();
                $table->bigInteger('amount'); // Amount in IRR (Rial)
                $table->text('description')->nullable();
                $table->enum('gateway', ['zarinpal'])->default('zarinpal');
                $table->enum('status', ['pending', 'completed', 'failed', 'cancelled', 'expired'])->default('pending');
                $table->string('callback_url')->nullable();
                $table->string('error_code')->nullable();
                $table->text('error_message')->nullable();
                $table->timestamp('expires_at')->nullable();
                $table->timestamp('verified_at')->nullable();
                $table->json('metadata')->nullable();
                $table->timestamps();

                $table->index(['user_id', 'status']);
                $table->index(['tracking_code', 'status']);
                $table->index(['gateway', 'status']);
                $table->index('created_at');
            });
        } else {
            // If table exists, check for missing columns and add them
            Schema::table('payments', function (Blueprint $table) {
                if (!Schema::hasColumn('payments', 'tracking_code')) {
                    $table->string('tracking_code')->unique()->after('user_id');
                }
                if (!Schema::hasColumn('payments', 'authority')) {
                    $table->string('authority')->nullable()->after('tracking_code');
                }
                if (!Schema::hasColumn('payments', 'reference_id')) {
                    $table->string('reference_id')->nullable()->after('authority');
                }
                if (!Schema::hasColumn('payments', 'gateway')) {
                    $table->enum('gateway', ['zarinpal'])->default('zarinpal')->after('description');
                }
                if (!Schema::hasColumn('payments', 'callback_url')) {
                    $table->string('callback_url')->nullable()->after('status');
                }
                if (!Schema::hasColumn('payments', 'error_code')) {
                    $table->string('error_code')->nullable()->after('callback_url');
                }
                if (!Schema::hasColumn('payments', 'error_message')) {
                    $table->text('error_message')->nullable()->after('error_code');
                }
                if (!Schema::hasColumn('payments', 'expires_at')) {
                    $table->timestamp('expires_at')->nullable()->after('error_message');
                }
                if (!Schema::hasColumn('payments', 'verified_at')) {
                    $table->timestamp('verified_at')->nullable()->after('expires_at');
                }
                if (!Schema::hasColumn('payments', 'metadata')) {
                    $table->json('metadata')->nullable()->after('verified_at');
                }
            });

            // Add indexes if they don't exist
            try {
                Schema::table('payments', function (Blueprint $table) {
                    if (!$this->indexExists('payments', 'payments_user_id_status_index')) {
                        $table->index(['user_id', 'status']);
                    }
                    if (!$this->indexExists('payments', 'payments_tracking_code_status_index')) {
                        $table->index(['tracking_code', 'status']);
                    }
                    if (!$this->indexExists('payments', 'payments_gateway_status_index')) {
                        $table->index(['gateway', 'status']);
                    }
                });
            } catch (\Exception $e) {
                // Ignore index creation errors in case they already exist
            }
        }
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('payments');
    }

    /**
     * Check if index exists
     */
    private function indexExists(string $table, string $index): bool
    {
        $indexes = Schema::getConnection()->getDoctrineSchemaManager()->listTableIndexes($table);
        return array_key_exists($index, $indexes);
    }
};