<?php

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

/**
 * Agents (§12). An agent may be an external field agent with a portal login or
 * an internal staff member; either way the record carries its own identity,
 * territory, contract and payout details.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('agents', function (Blueprint $table) {
            $table->id();
            $table->uuid('uuid')->unique();
            $table->string('agent_code', 32);

            $table->foreignId('company_id')->constrained()->cascadeOnUpdate()->restrictOnDelete();
            $table->foreignId('branch_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('team_id')->nullable()->constrained()->nullOnDelete();
            // Portal login, when the agent has one.
            $table->foreignId('user_id')->nullable()->unique()->constrained()->nullOnDelete();
            // Reporting line: a senior agent or agent manager.
            $table->foreignId('supervisor_id')->nullable()->constrained('agents')->nullOnDelete();

            $table->string('name');
            $table->string('local_name')->nullable();
            $table->string('photo_path')->nullable();
            $table->string('phone', 32);
            $table->string('whatsapp', 32)->nullable();
            $table->string('email')->nullable();
            $table->string('national_id', 50)->nullable();
            $table->date('date_of_birth')->nullable();

            $table->text('address')->nullable();
            $table->string('district', 100)->nullable();
            $table->string('upazila', 100)->nullable();
            $table->string('territory')->nullable();

            $table->string('agent_type', 20)->default('external');
            $table->string('status', 20)->default('pending_approval');
            $table->date('joining_date')->nullable();
            $table->date('contract_start_date')->nullable();
            $table->date('contract_end_date')->nullable();

            $table->string('bank_name')->nullable();
            $table->string('bank_branch')->nullable();
            $table->string('bank_account_name')->nullable();
            $table->string('bank_account_number', 64)->nullable();
            $table->string('mobile_wallet_provider', 40)->nullable();
            $table->string('mobile_wallet_number', 32)->nullable();

            // Monthly registration/deployment target used by the agent dashboard.
            $table->unsignedInteger('monthly_target')->nullable();

            $table->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('approved_at')->nullable();
            $table->text('status_reason')->nullable();
            $table->text('notes')->nullable();

            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamps();
            $table->softDeletes();

            $table->unique(['company_id', 'agent_code']);
            $table->index(['company_id', 'branch_id', 'status']);
            $table->index('phone');
            $table->index('national_id');
            $table->index('name');
        });

        // Every status change is recorded; approvals and suspensions are audited (§65).
        Schema::create('agent_status_histories', function (Blueprint $table) {
            $table->id();
            $table->foreignId('agent_id')->constrained()->cascadeOnDelete();
            $table->string('from_status', 20)->nullable();
            $table->string('to_status', 20);
            $table->text('reason')->nullable();
            $table->foreignId('changed_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('changed_at');
            $table->timestamps();

            $table->index(['agent_id', 'changed_at']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('agent_status_histories');
        Schema::dropIfExists('agents');
    }
};
