<?php

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

/**
 * Applicants (§9). The central record of the system: everything downstream —
 * documents, processing, billing, commission — hangs off it.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('applicants', function (Blueprint $table) {
            $table->id();
            $table->uuid('uuid')->unique();
            // Human-readable tracking reference: AT-DHK-2026-000001 (§9.3).
            $table->string('reference_no', 40);

            $table->foreignId('company_id')->constrained()->cascadeOnUpdate()->restrictOnDelete();
            $table->foreignId('branch_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('agent_id')->nullable()->constrained()->nullOnDelete();
            // Staff member handling the file.
            $table->foreignId('assigned_to')->nullable()->constrained('users')->nullOnDelete();
            // Applicant portal login, created on demand.
            $table->foreignId('user_id')->nullable()->unique()->constrained()->nullOnDelete();
            $table->foreignId('employer_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('job_demand_id')->nullable()->constrained()->nullOnDelete();

            // Personal information
            $table->string('full_name');
            $table->string('local_name')->nullable();
            $table->string('father_name')->nullable();
            $table->string('mother_name')->nullable();
            $table->string('spouse_name')->nullable();
            $table->string('gender', 10)->nullable();
            $table->date('date_of_birth')->nullable();
            $table->string('nationality', 60)->nullable();
            $table->string('religion', 40)->nullable();
            $table->string('marital_status', 20)->nullable();
            $table->string('blood_group', 5)->nullable();
            $table->string('photo_path')->nullable();

            // Identity
            $table->string('national_id', 50)->nullable();
            $table->string('birth_registration_no', 50)->nullable();
            $table->string('passport_number', 50)->nullable();
            $table->date('passport_issue_date')->nullable();
            $table->date('passport_expiry_date')->nullable();
            $table->string('passport_issue_place', 120)->nullable();
            $table->string('passport_status', 30)->default('not_submitted');

            // Contact
            $table->string('mobile', 32)->nullable();
            $table->string('whatsapp', 32)->nullable();
            $table->string('email')->nullable();
            $table->text('present_address')->nullable();
            $table->text('permanent_address')->nullable();
            $table->string('district', 100)->nullable();
            $table->string('police_station', 100)->nullable();
            $table->string('postal_code', 20)->nullable();
            $table->string('emergency_contact_name')->nullable();
            $table->string('emergency_contact_relation', 50)->nullable();
            $table->string('emergency_contact_mobile', 32)->nullable();

            // Professional
            $table->string('occupation', 120)->nullable();
            $table->string('desired_occupation', 120)->nullable();
            $table->unsignedTinyInteger('experience_years')->nullable();
            $table->text('skills')->nullable();
            $table->text('certifications')->nullable();
            $table->string('education_level', 120)->nullable();
            $table->text('languages')->nullable();
            $table->boolean('has_overseas_experience')->default(false);
            $table->string('previous_country', 60)->nullable();
            $table->string('previous_employer')->nullable();
            $table->string('employment_status', 40)->nullable();
            $table->unsignedBigInteger('expected_salary_amount')->nullable();
            $table->char('expected_salary_currency', 3)->nullable();
            $table->string('preferred_country', 60)->nullable();
            $table->string('driving_license_no', 60)->nullable();
            $table->string('driving_license_type', 60)->nullable();

            // Recruitment
            $table->string('source', 40)->default('agent');
            $table->string('referral_name')->nullable();
            $table->string('campaign', 120)->nullable();
            $table->string('destination_country', 2)->nullable();
            $table->unsignedBigInteger('expected_fee_amount')->nullable();
            $table->char('fee_currency', 3)->nullable();

            $table->string('status', 30)->default('lead');
            $table->text('status_reason')->nullable();
            // Set once the applicant's own submission has been checked by staff.
            $table->timestamp('verified_at')->nullable();
            $table->foreignId('verified_by')->nullable()->constrained('users')->nullOnDelete();
            // Points at the surviving record when duplicates are merged (§9.2).
            $table->foreignId('merged_into_id')->nullable()->constrained('applicants')->nullOnDelete();

            $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', 'reference_no']);
            $table->index(['company_id', 'branch_id', 'status']);
            $table->index(['company_id', 'agent_id']);
            $table->index(['job_demand_id', 'status']);
            // Duplicate detection reads these constantly (§9.2).
            $table->index(['company_id', 'national_id']);
            $table->index(['company_id', 'passport_number']);
            $table->index(['company_id', 'mobile']);
            $table->index('full_name');
        });
    }

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