<?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('merchants')) Schema::create('merchants',function(Blueprint $t){$t->id();$t->string('public_id',40)->unique();$t->string('name');$t->string('email')->unique();$t->string('password');$t->string('status')->index();$t->timestampTz('email_verified_at')->nullable();$t->boolean('two_factor_enabled')->default(false);$t->text('two_factor_secret')->nullable();$t->rememberToken();$t->timestampsTz();});
 if(!Schema::hasTable('api_keys')) Schema::create('api_keys',function(Blueprint $t){$t->id();$t->foreignId('merchant_id')->constrained()->cascadeOnDelete();$t->string('key_prefix',32);$t->char('public_key_hash',64)->unique();$t->text('secret_ciphertext');$t->string('secret_kid');$t->json('scopes');$t->string('environment',16);$t->string('status',20)->index();$t->timestampTz('last_used_at')->nullable();$t->timestampsTz();$t->index(['merchant_id','environment']);});
 if(!Schema::hasTable('assets')) Schema::create('assets',function(Blueprint $t){$t->id();$t->string('code',20);$t->string('name')->default('');$t->string('network',30);$t->string('contract_address')->nullable();$t->unsignedSmallInteger('decimals');$t->decimal('min_amount_atomic',65,0)->default(0);$t->json('confirmation_policy');$t->boolean('enabled')->default(false);$t->timestampsTz();$t->unique(['network','code','contract_address']);});
 if(!Schema::hasTable('wallets')) Schema::create('wallets',function(Blueprint $t){$t->id();$t->foreignId('merchant_id')->nullable()->constrained()->nullOnDelete();$t->string('network');$t->string('provider');$t->string('provider_wallet_id')->unique();$t->text('xpub_reference')->nullable();$t->string('status');$t->timestampsTz();});
 if(!Schema::hasTable('invoices')) Schema::create('invoices',function(Blueprint $t){$t->id();$t->string('public_id',40)->unique();$t->foreignId('merchant_id')->constrained()->restrictOnDelete();$t->string('environment',16);$t->string('order_id')->nullable();$t->bigInteger('price_amount_minor');$t->char('price_currency',3);$t->foreignId('pay_asset_id')->constrained('assets');$t->decimal('quoted_pay_amount_atomic',65,0);$t->decimal('quote_rate',36,18)->nullable();$t->timestampTz('quote_expires_at')->nullable();$t->text('ipn_callback_url')->nullable();$t->text('success_url')->nullable();$t->text('cancel_url')->nullable();$t->decimal('paid_amount_atomic',65,0)->default(0);$t->string('status',30);$t->timestampTz('expires_at')->nullable();$t->json('metadata')->default('{}');$t->timestampsTz();$t->index(['merchant_id','status']);$t->index(['status','expires_at']);$t->unique(['merchant_id','order_id','environment']);});
 if(!Schema::hasTable('wallet_addresses')) Schema::create('wallet_addresses',function(Blueprint $t){$t->id();$t->foreignId('wallet_id')->nullable()->constrained()->nullOnDelete();$t->foreignId('invoice_id')->unique()->constrained()->cascadeOnDelete();$t->string('network');$t->string('address');$t->unsignedBigInteger('derivation_index')->nullable();$t->string('provider_ref')->nullable();$t->string('environment',16);$t->timestampsTz();$t->unique(['network','address']);});
 if(!Schema::hasTable('chain_transactions')) Schema::create('chain_transactions',function(Blueprint $t){$t->id();$t->string('network');$t->string('tx_hash');$t->foreignId('asset_id')->constrained();$t->string('from_address')->nullable();$t->string('to_address');$t->decimal('amount_atomic',65,0);$t->unsignedBigInteger('block_height')->nullable();$t->unsignedInteger('confirmations')->default(0);$t->string('finality_status');$t->timestampTz('detected_at')->nullable();$t->unsignedInteger('transfer_index')->default(0);$t->timestampsTz();$t->unique(['network','tx_hash','transfer_index']);});
 if(!Schema::hasTable('invoice_transactions')) Schema::create('invoice_transactions',function(Blueprint $t){$t->id();$t->foreignId('invoice_id')->constrained()->cascadeOnDelete();$t->foreignId('chain_transaction_id')->constrained()->restrictOnDelete();$t->decimal('allocated_amount_atomic',65,0);$t->timestampsTz();$t->unique(['invoice_id','chain_transaction_id']);});
 if(!Schema::hasTable('ledger_accounts')) Schema::create('ledger_accounts',function(Blueprint $t){$t->id();$t->foreignId('merchant_id')->nullable()->constrained()->restrictOnDelete();$t->string('type');$t->foreignId('asset_id')->constrained();$t->string('status');$t->timestampsTz();$t->unique(['merchant_id','type','asset_id']);});
 if(!Schema::hasTable('ledger_transactions')) Schema::create('ledger_transactions',function(Blueprint $t){$t->id();$t->string('public_id',40)->unique();$t->string('reference_type');$t->string('reference_id');$t->string('idempotency_key')->unique();$t->timestampTz('posted_at')->nullable();$t->foreignId('reversed_by_id')->nullable()->constrained('ledger_transactions');});
 if(!Schema::hasTable('ledger_entries')) Schema::create('ledger_entries',function(Blueprint $t){$t->id();$t->foreignId('ledger_transaction_id')->constrained()->restrictOnDelete();$t->foreignId('account_id')->constrained('ledger_accounts')->restrictOnDelete();$t->string('direction',6);$t->decimal('amount_atomic',65,0);});
 if(!Schema::hasTable('webhook_endpoints')) Schema::create('webhook_endpoints',function(Blueprint $t){$t->id();$t->foreignId('merchant_id')->constrained()->cascadeOnDelete();$t->text('url');$t->text('secret_ciphertext');$t->json('events');$t->string('status');$t->string('environment',16);$t->timestampsTz();});
 if(!Schema::hasTable('webhook_deliveries')) Schema::create('webhook_deliveries',function(Blueprint $t){$t->id();$t->uuid('event_id');$t->foreignId('endpoint_id')->constrained('webhook_endpoints')->cascadeOnDelete();$t->json('payload');$t->string('signature')->nullable();$t->unsignedInteger('attempt_count')->default(0);$t->timestampTz('next_attempt_at')->nullable();$t->string('status');$t->unsignedSmallInteger('last_response_code')->nullable();$t->text('last_error')->nullable();$t->timestampsTz();$t->unique(['event_id','endpoint_id']);});
 if(!Schema::hasTable('payouts')) Schema::create('payouts',function(Blueprint $t){$t->id();$t->string('public_id',40)->unique();$t->foreignId('merchant_id')->constrained()->restrictOnDelete();$t->string('environment',16);$t->foreignId('asset_id')->constrained();$t->string('to_address');$t->decimal('amount_atomic',65,0);$t->decimal('fee_atomic',65,0)->default(0);$t->string('status')->index();$t->string('idempotency_key');$t->string('provider_transfer_id')->nullable();$t->string('tx_hash')->nullable();$t->timestampsTz();$t->unique(['merchant_id','idempotency_key']);});
 if(!Schema::hasTable('payout_approvals')) Schema::create('payout_approvals',function(Blueprint $t){$t->id();$t->foreignId('payout_id')->constrained()->cascadeOnDelete();$t->unsignedBigInteger('approver_id');$t->string('decision');$t->text('reason')->nullable();$t->timestampTz('decided_at')->nullable();$t->unique(['payout_id','approver_id']);});
 if(!Schema::hasTable('provider_events')) Schema::create('provider_events',function(Blueprint $t){$t->id();$t->string('provider');$t->string('external_event_id');$t->json('raw_payload');$t->boolean('verified');$t->timestampTz('processed_at')->nullable();$t->timestampsTz();$t->unique(['provider','external_event_id']);});
 if(!Schema::hasTable('reconciliation_runs')) Schema::create('reconciliation_runs',function(Blueprint $t){$t->id();$t->string('network');$t->foreignId('asset_id')->constrained();$t->string('environment',16);$t->timestampTz('started_at')->nullable();$t->timestampTz('completed_at')->nullable();$t->string('status');$t->decimal('difference_atomic',65,0)->default(0);$t->json('details')->default('{}');$t->timestampsTz();$t->index(['network','asset_id','started_at']);});
 if(!Schema::hasTable('audit_logs')) Schema::create('audit_logs',function(Blueprint $t){$t->id();$t->string('actor_type');$t->string('actor_id')->nullable();$t->foreignId('merchant_id')->nullable()->constrained()->nullOnDelete();$t->string('action')->index();$t->string('subject');$t->json('metadata')->default('{}');$t->ipAddress('ip')->nullable();$t->text('user_agent')->nullable();$t->timestampTz('created_at')->nullable()->useCurrent();});
 }
 public function down():void { foreach(['audit_logs','reconciliation_runs','provider_events','payout_approvals','payouts','webhook_deliveries','webhook_endpoints','ledger_entries','ledger_transactions','ledger_accounts','invoice_transactions','chain_transactions','wallet_addresses','invoices','wallets','assets','api_keys','merchants'] as $table)Schema::dropIfExists($table); }
};
