<?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
    {
        Schema::create('topology_device_types', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->nullable()->constrained()->cascadeOnDelete();
            $table->string('code', 50);
            $table->string('name');
            $table->string('category', 50);
            $table->boolean('can_have_ports')->default(true);
            $table->boolean('can_have_splitters')->default(false);
            $table->boolean('is_system')->default(false);
            $table->string('icon')->nullable();
            $table->string('color', 20)->default('#2f74c0');
            $table->string('status', 20)->default('active');
            $table->timestamps();
            $table->unique(['tenant_id', 'code']);
            $table->index(['tenant_id', 'status']);
        });

        Schema::create('topology_nodes', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('device_type_id')->constrained('topology_device_types')->restrictOnDelete();
            $table->foreignId('parent_node_id')->nullable()->constrained('topology_nodes')->nullOnDelete();
            $table->foreignId('provinsi_id')->nullable()->constrained('wilayah_provinsi')->nullOnDelete();
            $table->foreignId('kabupaten_id')->nullable()->constrained('wilayah_kabupaten')->nullOnDelete();
            $table->foreignId('kecamatan_id')->nullable()->constrained('wilayah_kecamatan')->nullOnDelete();
            $table->foreignId('desa_id')->nullable()->constrained('wilayah_desa')->nullOnDelete();
            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
            $table->string('code');
            $table->string('name');
            $table->text('description')->nullable();
            $table->string('status', 30)->default('active');
            $table->decimal('latitude', 10, 7);
            $table->decimal('longitude', 10, 7);
            $table->text('address')->nullable();
            $table->unsignedInteger('capacity')->nullable();
            $table->date('installed_at')->nullable();
            $table->decimal('diagram_x', 12, 2)->nullable();
            $table->decimal('diagram_y', 12, 2)->nullable();
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->softDeletes();
            $table->unique(['tenant_id', 'code']);
            $table->index(['tenant_id', 'device_type_id', 'status']);
            $table->index(['tenant_id', 'latitude', 'longitude']);
        });

        Schema::create('topology_ports', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('node_id')->constrained('topology_nodes')->cascadeOnDelete();
            $table->string('name');
            $table->unsignedInteger('port_number');
            $table->string('port_type', 50)->default('fiber');
            $table->string('direction', 20)->default('bidirectional');
            $table->unsignedInteger('capacity')->default(1);
            $table->string('status', 30)->default('available');
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->unique(['node_id', 'port_number']);
            $table->index(['tenant_id', 'status']);
        });

        Schema::create('topology_links', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('source_node_id')->constrained('topology_nodes')->restrictOnDelete();
            $table->foreignId('source_port_id')->nullable()->constrained('topology_ports')->restrictOnDelete();
            $table->foreignId('target_node_id')->constrained('topology_nodes')->restrictOnDelete();
            $table->foreignId('target_port_id')->nullable()->constrained('topology_ports')->restrictOnDelete();
            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
            $table->string('code');
            $table->string('name');
            $table->string('link_type', 30)->default('fiber');
            $table->string('fiber_type', 50)->nullable();
            $table->unsignedInteger('core_count')->nullable();
            $table->decimal('cable_length', 12, 2)->nullable();
            $table->decimal('measured_length', 12, 2)->nullable();
            $table->json('path_geojson')->nullable();
            $table->string('status', 30)->default('active');
            $table->date('installed_at')->nullable();
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->softDeletes();
            $table->unique(['tenant_id', 'code']);
            $table->unique(['source_node_id', 'target_node_id', 'source_port_id', 'target_port_id'], 'topology_links_endpoints_unique');
            $table->index(['tenant_id', 'status', 'link_type']);
        });

        Schema::create('topology_connection_rules', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->nullable()->constrained()->cascadeOnDelete();
            $table->foreignId('source_device_type_id')->constrained('topology_device_types')->cascadeOnDelete();
            $table->foreignId('target_device_type_id')->constrained('topology_device_types')->cascadeOnDelete();
            $table->boolean('allowed')->default(true);
            $table->unsignedInteger('max_connections')->nullable();
            $table->timestamps();
            $table->unique(['tenant_id', 'source_device_type_id', 'target_device_type_id'], 'topology_rules_unique');
        });

        Schema::create('topology_splitters', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('node_id')->constrained('topology_nodes')->cascadeOnDelete();
            $table->foreignId('input_port_id')->nullable()->constrained('topology_ports')->nullOnDelete();
            $table->string('ratio', 20);
            $table->unsignedTinyInteger('level')->default(1);
            $table->decimal('insertion_loss_db', 6, 2)->nullable();
            $table->string('status', 30)->default('active');
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->index(['tenant_id', 'node_id']);
        });

        Schema::create('topology_customer_connections', function (Blueprint $table) {
            $table->id();
            $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
            $table->foreignId('customer_id')->constrained()->cascadeOnDelete();
            $table->foreignId('odp_node_id')->constrained('topology_nodes')->restrictOnDelete();
            $table->foreignId('odp_port_id')->nullable()->constrained('topology_ports')->restrictOnDelete();
            $table->foreignId('drop_cable_link_id')->nullable()->constrained('topology_links')->nullOnDelete();
            $table->timestamp('connected_at')->nullable();
            $table->timestamp('disconnected_at')->nullable();
            $table->string('status', 30)->default('active');
            $table->json('metadata')->nullable();
            $table->timestamps();
            $table->index(['customer_id', 'status']);
            $table->index(['tenant_id', 'odp_node_id', 'status']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('topology_customer_connections');
        Schema::dropIfExists('topology_splitters');
        Schema::dropIfExists('topology_connection_rules');
        Schema::dropIfExists('topology_links');
        Schema::dropIfExists('topology_ports');
        Schema::dropIfExists('topology_nodes');
        Schema::dropIfExists('topology_device_types');
    }
};
