<?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('warehouses')) {
            Schema::create('warehouses', function (Blueprint $table): void {
                $table->id();
                $table->string('code', 50)->unique();
                $table->string('name');
                $table->string('contact_number', 20)->nullable();
                $table->string('manager_name')->nullable();
                $table->text('address')->nullable();
                $table->string('city')->nullable();
                $table->string('state')->nullable();
                $table->string('pincode', 12)->nullable()->index();
                $table->boolean('is_active')->default(true)->index();
                $table->timestamps();
            });
        }

        if (! Schema::hasTable('warehouse_stocks')) {
            Schema::create('warehouse_stocks', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('warehouse_id')->constrained('warehouses')->cascadeOnDelete();
                $table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
                $table->decimal('quantity', 14, 4)->default(0);
                $table->decimal('reserved_quantity', 14, 4)->default(0);
                $table->timestamps();
                $table->unique(['warehouse_id', 'product_id'], 'warehouse_stocks_unique');
            });
        }

        if (! Schema::hasTable('warehouse_stock_logs')) {
            Schema::create('warehouse_stock_logs', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('warehouse_id')->constrained('warehouses')->cascadeOnDelete();
                $table->foreignId('franchise_id')->nullable()->constrained('franchises')->nullOnDelete();
                $table->foreignId('product_id')->constrained('products')->cascadeOnDelete();
                $table->enum('transaction_type', ['stock_in', 'stock_out', 'dispatch_to_franchise', 'return_from_franchise', 'adjustment'])->index();
                $table->decimal('quantity', 14, 4);
                $table->decimal('opening_qty', 14, 4)->default(0);
                $table->decimal('closing_qty', 14, 4)->default(0);
                $table->string('reference', 120)->nullable()->index();
                $table->jsonOrLongText('meta')->nullable();
                $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
                $table->timestamp('transacted_at')->useCurrent()->index();
                $table->timestamps();
            });
        }

        if (! Schema::hasTable('franchise_territories')) {
            Schema::create('franchise_territories', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('franchise_id')->constrained('franchises')->cascadeOnDelete();
                $table->foreignId('warehouse_id')->nullable()->constrained('warehouses')->nullOnDelete();
                $table->string('state')->nullable();
                $table->string('district')->nullable();
                $table->string('area_name')->nullable();
                $table->string('pincode', 12)->index();
                $table->boolean('is_active')->default(true)->index();
                $table->timestamps();
                $table->unique(['pincode', 'is_active'], 'franchise_territories_pincode_active_unique');
            });
        }

        if (! Schema::hasTable('franchise_commission_rules')) {
            Schema::create('franchise_commission_rules', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('franchise_id')->nullable()->constrained('franchises')->nullOnDelete();
                $table->enum('rule_type', ['sale_margin', 'id_activation', 'service_charge', 'pickup_fee'])->index();
                $table->enum('calc_type', ['percent', 'fixed'])->default('percent');
                $table->decimal('value', 12, 4)->default(0);
                $table->decimal('min_base_amount', 14, 2)->nullable();
                $table->decimal('max_base_amount', 14, 2)->nullable();
                $table->date('effective_from')->nullable();
                $table->date('effective_to')->nullable();
                $table->boolean('is_active')->default(true)->index();
                $table->timestamps();
                $table->index(['franchise_id', 'rule_type', 'is_active'], 'franchise_commission_rule_lookup');
            });
        }

        if (Schema::hasTable('franchise_stock_requests') && ! Schema::hasColumn('franchise_stock_requests', 'requested_warehouse_id')) {
            Schema::table('franchise_stock_requests', function (Blueprint $table): void {
                $table->foreignId('requested_warehouse_id')->nullable()->after('franchise_id')->constrained('warehouses')->nullOnDelete();
            });
        }
    }

    public function down(): void
    {
        if (Schema::hasTable('franchise_stock_requests') && Schema::hasColumn('franchise_stock_requests', 'requested_warehouse_id')) {
            Schema::table('franchise_stock_requests', function (Blueprint $table): void {
                $table->dropConstrainedForeignId('requested_warehouse_id');
            });
        }

        Schema::dropIfExists('franchise_commission_rules');
        Schema::dropIfExists('franchise_territories');
        Schema::dropIfExists('warehouse_stock_logs');
        Schema::dropIfExists('warehouse_stocks');
        Schema::dropIfExists('warehouses');
    }
};

