<?php
// =====================================================================
// MIGRATION: 2024_01_01_000001_create_all_tables.php
// Run: php artisan migrate
// =====================================================================
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    public function up(): void
    {
        // USERS (internal: admin, cs, technician)
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->enum('role', ['admin', 'cs', 'technician'])->default('cs');
            $table->enum('division', ['JPN', 'FixLab', 'Havva'])->default('JPN');
            $table->string('phone')->nullable();
            $table->boolean('is_active')->default(true);
            $table->string('google2fa_secret')->nullable();
            $table->boolean('two_factor_enabled')->default(false);
            $table->string('telegram_chat_id')->nullable();
            $table->string('whatsapp_number')->nullable();
            $table->json('notification_prefs')->nullable(); // {email,wa,telegram,inapp}
            $table->rememberToken();
            $table->timestamps();
        });

        // CLIENTS
        Schema::create('clients', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->enum('type', ['maintenance', 'non_maintenance', 'individual']);
            $table->enum('division', ['JPN', 'FixLab', 'Havva'])->default('JPN');
            $table->string('company_name')->nullable();
            $table->string('email')->nullable();
            $table->string('phone')->nullable();
            $table->string('address')->nullable();
            $table->string('pic_name')->nullable(); // Person In Charge
            $table->string('pic_phone')->nullable();
            // Maintenance config
            $table->integer('max_visits_per_month')->default(0);
            $table->decimal('monthly_fee', 12, 2)->default(0);
            $table->decimal('extra_visit_fee', 12, 2)->default(0);
            $table->boolean('sla_enabled')->default(false);
            $table->date('contract_start')->nullable();
            $table->date('contract_end')->nullable();
            $table->boolean('is_active')->default(true);
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        // CLIENT USERS (people inside client company)
        Schema::create('client_users', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->string('name');
            $table->string('email')->nullable();
            $table->string('phone')->nullable();
            $table->string('department')->nullable();
            $table->string('position')->nullable();
            $table->string('password')->nullable(); // for portal login
            $table->boolean('can_login')->default(false);
            $table->boolean('is_active')->default(true);
            $table->timestamps();
        });

        // DEVICES (assets belonging to client users)
        Schema::create('devices', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('client_user_id')->nullable()->constrained()->nullOnDelete();
            $table->enum('type', ['laptop', 'pc', 'printer', 'router', 'switch', 'cctv', 'other']);
            $table->string('brand')->nullable();
            $table->string('model')->nullable();
            $table->string('serial_number')->nullable();
            $table->text('specs')->nullable(); // RAM, CPU, HDD etc
            $table->enum('condition', ['good', 'fair', 'poor'])->default('good');
            $table->date('purchase_date')->nullable();
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        // ISP (Internet Service Providers at client sites)
        Schema::create('isps', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->string('provider_name');
            $table->string('package')->nullable();
            $table->string('bandwidth')->nullable();
            $table->string('ip_address')->nullable();
            $table->string('account_number')->nullable();
            $table->string('support_contact')->nullable();
            $table->boolean('is_active')->default(true);
            $table->timestamps();
        });

        // ISP INCIDENTS (downtime log)
        Schema::create('isp_incidents', function (Blueprint $table) {
            $table->id();
            $table->foreignId('isp_id')->constrained()->cascadeOnDelete();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->dateTime('down_at');
            $table->dateTime('up_at')->nullable();
            $table->text('description')->nullable();
            $table->enum('status', ['ongoing', 'resolved'])->default('ongoing');
            $table->timestamps();
        });

        // SLA CONFIGS
        Schema::create('sla_configs', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id')->nullable()->constrained()->nullOnDelete();
            $table->string('name')->default('Default SLA');
            $table->boolean('is_default')->default(false);
            // Response time in minutes per priority
            $table->integer('critical_response')->default(60);
            $table->integer('high_response')->default(240);
            $table->integer('medium_response')->default(480);
            $table->integer('low_response')->default(1440);
            // Solve time in minutes per priority
            $table->integer('critical_solve')->default(240);
            $table->integer('high_solve')->default(480);
            $table->integer('medium_solve')->default(1440);
            $table->integer('low_solve')->default(4320);
            $table->timestamps();
        });

        // TICKETS
        Schema::create('tickets', function (Blueprint $table) {
            $table->id();
            $table->string('ticket_number')->unique(); // TKT-2024-XXXX
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('client_user_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('device_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('assigned_to')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('created_by')->constrained('users');
            $table->enum('division', ['JPN', 'FixLab', 'Havva'])->default('JPN');
            $table->string('subject');
            $table->text('description');
            $table->enum('priority', ['critical', 'high', 'medium', 'low'])->default('medium');
            $table->enum('status', ['open', 'in_progress', 'waiting_client', 'resolved', 'closed'])->default('open');
            $table->enum('source', ['portal', 'email', 'whatsapp', 'phone', 'manual'])->default('manual');
            $table->enum('category', ['network', 'hardware', 'software', 'cctv', 'other'])->default('other');
            // SLA
            $table->foreignId('sla_config_id')->nullable()->constrained()->nullOnDelete();
            $table->dateTime('sla_response_deadline')->nullable();
            $table->dateTime('sla_solve_deadline')->nullable();
            $table->dateTime('sla_responded_at')->nullable();
            $table->dateTime('sla_solved_at')->nullable();
            $table->enum('sla_status', ['ok', 'warning', 'breach'])->default('ok');
            // Resolution
            $table->text('resolution')->nullable();
            $table->dateTime('resolved_at')->nullable();
            $table->dateTime('closed_at')->nullable();
            $table->timestamps();
        });

        // TICKET COMMENTS
        Schema::create('ticket_comments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('ticket_id')->constrained()->cascadeOnDelete();
            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('client_user_id')->nullable()->constrained()->nullOnDelete();
            $table->text('body');
            $table->boolean('is_internal')->default(false); // internal note
            $table->timestamps();
        });

        // TICKET ATTACHMENTS
        Schema::create('ticket_attachments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('ticket_id')->constrained()->cascadeOnDelete();
            $table->string('filename');
            $table->string('original_name');
            $table->string('mime_type');
            $table->integer('file_size');
            $table->string('path');
            $table->foreignId('uploaded_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamps();
        });

        // VISITS (field visits)
        Schema::create('visits', function (Blueprint $table) {
            $table->id();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('ticket_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('technician_id')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('created_by')->constrained('users');
            $table->date('visit_date');
            $table->time('visit_time_start')->nullable();
            $table->time('visit_time_end')->nullable();
            $table->enum('status', ['scheduled', 'in_progress', 'done', 'cancelled'])->default('scheduled');
            $table->text('purpose')->nullable();
            $table->text('notes')->nullable();
            $table->boolean('is_extra')->default(false); // beyond contract limit
            $table->decimal('extra_charge', 12, 2)->default(0);
            $table->timestamps();
        });

        // FIXLAB WORK ORDERS
        Schema::create('work_orders', function (Blueprint $table) {
            $table->id();
            $table->string('wo_number')->unique(); // WO-2024-XXXX
            $table->foreignId('client_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('client_user_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('ticket_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('assigned_to')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('created_by')->constrained('users');
            $table->enum('division', ['FixLab', 'Havva'])->default('FixLab');
            $table->enum('type', ['repair', 'installation'])->default('repair');
            $table->string('item_name'); // nama perangkat
            $table->string('item_brand')->nullable();
            $table->string('item_serial')->nullable();
            $table->text('reported_issue');
            $table->text('diagnosis')->nullable();
            $table->text('action_taken')->nullable();
            $table->decimal('estimated_cost', 12, 2)->default(0);
            $table->decimal('final_cost', 12, 2)->default(0);
            $table->json('spareparts')->nullable(); // [{name, qty, price}]
            $table->enum('status', ['received','diagnosed','waiting_approval','in_repair','done','delivered','cancelled'])->default('received');
            $table->string('customer_name')->nullable();
            $table->string('customer_phone')->nullable();
            $table->dateTime('received_at')->nullable();
            $table->dateTime('delivered_at')->nullable();
            $table->string('delivery_signature')->nullable(); // base64 or path
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        // WORK ORDER PHOTOS
        Schema::create('work_order_photos', function (Blueprint $table) {
            $table->id();
            $table->foreignId('work_order_id')->constrained()->cascadeOnDelete();
            $table->string('path');
            $table->enum('type', ['before', 'after', 'delivery'])->default('before');
            $table->timestamps();
        });

        // PROJECTS (Havva CCTV installation)
        Schema::create('projects', function (Blueprint $table) {
            $table->id();
            $table->string('project_number')->unique();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('pic_id')->nullable()->constrained('users')->nullOnDelete();
            $table->string('title');
            $table->text('description')->nullable();
            $table->enum('status', ['survey','rab_submitted','approved','in_progress','testing','done','cancelled'])->default('survey');
            $table->decimal('rab_amount', 12, 2)->default(0);
            $table->decimal('final_amount', 12, 2)->default(0);
            $table->date('start_date')->nullable();
            $table->date('end_date')->nullable();
            $table->timestamps();
        });

        // INVOICES
        Schema::create('invoices', function (Blueprint $table) {
            $table->id();
            $table->string('invoice_number')->unique();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->foreignId('created_by')->constrained('users');
            $table->enum('division', ['JPN', 'FixLab', 'Havva'])->default('JPN');
            $table->enum('type', ['maintenance', 'extra_visit', 'work_order', 'project', 'other'])->default('maintenance');
            $table->date('issue_date');
            $table->date('due_date');
            $table->integer('billing_month')->nullable(); // 1-12
            $table->integer('billing_year')->nullable();
            $table->decimal('subtotal', 12, 2)->default(0);
            $table->decimal('tax_percent', 5, 2)->default(0);
            $table->decimal('tax_amount', 12, 2)->default(0);
            $table->decimal('total', 12, 2)->default(0);
            $table->decimal('amount_paid', 12, 2)->default(0);
            $table->enum('status', ['draft','sent','partial','paid','overdue','cancelled'])->default('draft');
            $table->text('notes')->nullable();
            $table->dateTime('paid_at')->nullable();
            $table->boolean('is_recurring')->default(false);
            $table->timestamps();
        });

        // INVOICE ITEMS
        Schema::create('invoice_items', function (Blueprint $table) {
            $table->id();
            $table->foreignId('invoice_id')->constrained()->cascadeOnDelete();
            $table->string('description');
            $table->integer('qty')->default(1);
            $table->decimal('unit_price', 12, 2)->default(0);
            $table->decimal('total', 12, 2)->default(0);
            $table->timestamps();
        });

        // PAYMENTS
        Schema::create('payments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('invoice_id')->constrained()->cascadeOnDelete();
            $table->foreignId('recorded_by')->constrained('users');
            $table->decimal('amount', 12, 2);
            $table->date('payment_date');
            $table->string('payment_method')->nullable(); // transfer, cash, etc
            $table->string('reference_number')->nullable();
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        // CSAT SURVEYS
        Schema::create('csat_surveys', function (Blueprint $table) {
            $table->id();
            $table->foreignId('ticket_id')->constrained()->cascadeOnDelete();
            $table->foreignId('client_id')->constrained()->cascadeOnDelete();
            $table->string('token')->unique();
            $table->integer('rating')->nullable(); // 1-5
            $table->text('feedback')->nullable();
            $table->dateTime('sent_at')->nullable();
            $table->dateTime('answered_at')->nullable();
            $table->enum('channel', ['email', 'whatsapp', 'telegram'])->default('email');
            $table->timestamps();
        });

        // NOTIFICATIONS
        Schema::create('notifications_log', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
            $table->string('notifiable_type')->nullable();
            $table->unsignedBigInteger('notifiable_id')->nullable();
            $table->string('title');
            $table->text('body');
            $table->enum('channel', ['email', 'whatsapp', 'telegram', 'inapp']);
            $table->enum('status', ['pending', 'sent', 'failed'])->default('pending');
            $table->dateTime('sent_at')->nullable();
            $table->boolean('is_read')->default(false);
            $table->timestamps();
        });

        // ACTIVITY LOG (custom, lightweight)
        Schema::create('activity_logs', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
            $table->foreignId('client_user_id')->nullable()->constrained()->nullOnDelete();
            $table->string('module'); // ticket, client, invoice, etc
            $table->string('action'); // created, updated, deleted, etc
            $table->string('subject_type')->nullable();
            $table->unsignedBigInteger('subject_id')->nullable();
            $table->text('description')->nullable();
            $table->json('old_values')->nullable();
            $table->json('new_values')->nullable();
            $table->string('ip_address')->nullable();
            $table->string('user_agent')->nullable();
            $table->timestamps();
        });

        // COMPANY SETTINGS (per division)
        Schema::create('company_settings', function (Blueprint $table) {
            $table->id();
            $table->enum('division', ['JPN', 'FixLab', 'Havva'])->unique();
            $table->string('company_name');
            $table->string('address')->nullable();
            $table->string('phone')->nullable();
            $table->string('email')->nullable();
            $table->string('logo_path')->nullable();
            $table->string('bank_name')->nullable();
            $table->string('bank_account')->nullable();
            $table->string('bank_account_name')->nullable();
            $table->text('invoice_footer')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('company_settings');
        Schema::dropIfExists('activity_logs');
        Schema::dropIfExists('notifications_log');
        Schema::dropIfExists('csat_surveys');
        Schema::dropIfExists('payments');
        Schema::dropIfExists('invoice_items');
        Schema::dropIfExists('invoices');
        Schema::dropIfExists('projects');
        Schema::dropIfExists('work_order_photos');
        Schema::dropIfExists('work_orders');
        Schema::dropIfExists('visits');
        Schema::dropIfExists('ticket_attachments');
        Schema::dropIfExists('ticket_comments');
        Schema::dropIfExists('tickets');
        Schema::dropIfExists('sla_configs');
        Schema::dropIfExists('isp_incidents');
        Schema::dropIfExists('isps');
        Schema::dropIfExists('devices');
        Schema::dropIfExists('client_users');
        Schema::dropIfExists('clients');
        Schema::dropIfExists('users');
    }
};
