<?php

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

return new class extends Migration {
    private array $recoverable = [
        'contacts', 'leads', 'deals', 'accounts', 'campaigns', 'tickets',
        'products', 'activities', 'notes', 'calls', 'tasks', 'events', 'deal_files',
    ];

    public function up(): void
    {
        foreach ($this->recoverable as $table) {
            if (Schema::hasTable($table) && ! Schema::hasColumn($table, 'deleted_at')) {
                Schema::table($table, fn (Blueprint $blueprint) => $blueprint->softDeletes());
            }
        }

        Schema::table('deals', function (Blueprint $table) {
            $table->unsignedTinyInteger('close_probability')->default(0)->after('estimate_amount');
            $table->decimal('forecast_value', 15, 2)->default(0)->after('close_probability');
            $table->text('comments')->nullable()->after('forecast_value');
            $table->string('lost_reason')->nullable()->after('comments');
            $table->string('lost_competitor')->nullable()->after('lost_reason');
            $table->string('delivery_status')->nullable()->after('lost_competitor');
            $table->string('payment_status')->nullable()->after('delivery_status');
            $table->string('payment_method')->nullable()->after('payment_status');
        });

        Schema::table('deal_files', function (Blueprint $table) {
            $table->string('category')->nullable();
            $table->text('description')->nullable();
            $table->unsignedInteger('version')->default(1);
        });

        Schema::create('crm_assignments', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->morphs('assignable');
            $table->foreignId('user_id')->index();
            $table->foreignId('assigned_by')->nullable()->index();
            $table->timestamps();
            $table->unique(['assignable_type', 'assignable_id', 'user_id'], 'crm_assignment_unique');
        });

        Schema::create('crm_status_histories', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->morphs('statusable');
            $table->string('from_status')->nullable();
            $table->string('to_status');
            $table->text('reason')->nullable();
            $table->foreignId('changed_by')->nullable()->index();
            $table->timestamp('changed_at');
            $table->timestamps();
        });

        Schema::create('crm_files', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->morphs('fileable');
            $table->string('name');
            $table->string('category')->nullable();
            $table->text('description')->nullable();
            $table->string('path');
            $table->string('original_name');
            $table->string('mime_type')->nullable();
            $table->unsignedBigInteger('size')->default(0);
            $table->unsignedInteger('version')->default(1);
            $table->foreignId('uploaded_by')->nullable()->index();
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('messages', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->string('type');
            $table->string('subject')->nullable();
            $table->string('from_address')->nullable();
            $table->text('to_addresses');
            $table->text('content');
            $table->string('status')->default('draft');
            $table->string('conversation_id')->nullable()->index();
            $table->nullableMorphs('related');
            $table->foreignId('owner_id')->nullable()->index();
            $table->timestamp('sent_at')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('follow_ups', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->string('title');
            $table->nullableMorphs('related');
            $table->foreignId('owner_id')->nullable()->index();
            $table->dateTime('follow_up_at');
            $table->string('priority')->default('medium');
            $table->string('status')->default('pending');
            $table->dateTime('remind_at')->nullable();
            $table->text('notes')->nullable();
            $table->foreignId('previous_activity_id')->nullable()->index();
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->string('title');
            $table->text('description')->nullable();
            $table->nullableMorphs('related');
            $table->foreignId('owner_id')->nullable()->index();
            $table->foreignId('created_by')->nullable()->index();
            $table->string('priority')->default('medium');
            $table->dateTime('due_at')->nullable();
            $table->dateTime('remind_at')->nullable();
            $table->string('category')->nullable();
            $table->string('status')->default('pending');
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('projects', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->foreignId('deal_id')->nullable()->index();
            $table->foreignId('owner_id')->nullable()->index();
            $table->string('name');
            $table->text('description')->nullable();
            $table->string('status')->default('planned');
            $table->date('start_date')->nullable();
            $table->date('due_date')->nullable();
            $table->unsignedTinyInteger('progress')->default(0);
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('cases', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->string('case_number')->unique();
            $table->string('subject');
            $table->foreignId('account_id')->nullable()->index();
            $table->foreignId('contact_id')->nullable()->index();
            $table->foreignId('assigned_to')->nullable()->index();
            $table->string('priority')->default('medium');
            $table->string('status')->default('new');
            $table->string('category')->nullable();
            $table->dateTime('due_at')->nullable();
            $table->text('description')->nullable();
            $table->text('resolution')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('surveys', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->foreignId('owner_id')->nullable()->index();
            $table->string('name');
            $table->text('description')->nullable();
            $table->string('type');
            $table->string('status')->default('draft');
            $table->string('target_audience')->nullable();
            $table->date('start_date')->nullable();
            $table->date('end_date')->nullable();
            $table->json('questions')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });

        Schema::create('trade_documents', function (Blueprint $table) {
            $table->id();
            $table->foreignId('business_id')->index();
            $table->foreignId('deal_id')->index();
            $table->foreignId('created_by')->nullable()->index();
            $table->string('type');
            $table->string('document_number')->index();
            $table->string('status')->default('draft');
            $table->string('currency', 8)->default('USD');
            $table->decimal('subtotal', 15, 2)->default(0);
            $table->decimal('discount', 15, 2)->default(0);
            $table->decimal('tax', 15, 2)->default(0);
            $table->decimal('total', 15, 2)->default(0);
            $table->date('issue_date');
            $table->date('due_date')->nullable();
            $table->text('notes')->nullable();
            $table->unsignedInteger('version')->default(1);
            $table->timestamps();
            $table->softDeletes();
            $table->unique(['business_id', 'document_number']);
        });

        Schema::create('trade_document_lines', function (Blueprint $table) {
            $table->id();
            $table->foreignId('trade_document_id')->index();
            $table->foreignId('product_id')->nullable()->index();
            $table->string('description');
            $table->decimal('quantity', 12, 3)->default(1);
            $table->decimal('unit_price', 15, 2)->default(0);
            $table->decimal('discount', 15, 2)->default(0);
            $table->decimal('tax', 15, 2)->default(0);
            $table->decimal('line_total', 15, 2)->default(0);
            $table->timestamps();
        });
    }

    public function down(): void
    {
        foreach (['trade_document_lines', 'trade_documents', 'surveys', 'cases', 'projects', 'todos',
            'follow_ups', 'messages', 'crm_files', 'crm_status_histories', 'crm_assignments'] as $table) {
            Schema::dropIfExists($table);
        }

        Schema::table('deal_files', fn (Blueprint $table) => $table->dropColumn(['category', 'description', 'version']));
        Schema::table('deals', fn (Blueprint $table) => $table->dropColumn([
            'close_probability', 'forecast_value', 'comments', 'lost_reason',
            'lost_competitor', 'delivery_status', 'payment_status', 'payment_method',
        ]));

        foreach ($this->recoverable as $table) {
            if (Schema::hasTable($table) && Schema::hasColumn($table, 'deleted_at')) {
                Schema::table($table, fn (Blueprint $blueprint) => $blueprint->dropSoftDeletes());
            }
        }
    }
};
