<?php

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

/**
 * İleti ↔ kayıt bağları — bir e-postayı satış / operasyon / müşteri ile ilişkilendirme.
 *
 * `mail_messages.customer_id` yalnızca TEK bir müşteriyi ve yalnızca adres
 * eşleşmesiyle taşıyabiliyordu. Gerçek yazışma bunu karşılamıyor:
 *
 *   • Bir tedarikçiyle yapılan otel yazışması aslında bir SATIŞI ilgilendirir;
 *     karşı taraf müşteri bile değildir.
 *   • Bir kalkışın (operasyon) rehber/araç yazışması hiçbir müşteri kartına
 *     ait değildir ama o operasyonun akışında görünmelidir.
 *   • Aynı ileti hem satışa hem müşteriye bağlı olabilir.
 *
 * Bu tablo bağı çok yönlü (morph) ve çoklu hâle getirir. `linkable_type` tam
 * sınıf adı olarak saklanır — projede morphMap kullanılmıyor, mevcut
 * polimorfik alanlar (customer_activities.related_type, tasks.related_type,
 * tour_operations.operatable_type) da tam sınıf adı yazıyor.
 *
 * `thread_key` işin can alıcı yeri: bağ kurulduğu andaki iletinin sohbet
 * anahtarı burada saklanır. Aynı yazışmaya gelen SONRAKİ cevaplar senkron
 * sırasında bu anahtardan (ya da In-Reply-To/References zincirinden) bulunup
 * aynı hedeflere otomatik bağlanır — kullanıcı her cevabı tek tek
 * ilişkilendirmek zorunda kalmaz. `is_auto` elle kurulan bağı zincirden
 * türeyenden ayırır; kullanıcı bağı kaldırdığında zincirden türeyen kardeşler
 * de birlikte temizlenebilsin diye gereklidir.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('mail_links', function (Blueprint $table) {
            $table->id();
            $table->foreignId('agency_id')->constrained('agencies')->cascadeOnDelete();
            $table->foreignId('message_id')->constrained('mail_messages')->cascadeOnDelete();

            // Customer · Sale · TourOperation · Supplier · Resource (tam sınıf adı)
            $table->string('linkable_type', 191);
            $table->unsignedBigInteger('linkable_id');

            // Bağ kurulduğu andaki sohbet anahtarı — cevapların otomatik
            // bağlanması bunun üzerinden yürür
            $table->string('thread_key', 191)->nullable();

            // false = kullanıcı elle bağladı · true = zincirden otomatik türedi
            $table->boolean('is_auto')->default(false);

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

            // Aynı ileti aynı kayda iki kez bağlanamaz
            $table->unique(['message_id', 'linkable_type', 'linkable_id'], 'mail_links_unique');
            // Kayıt kartı "bana bağlı postalar" sorgusunu bundan çeker
            $table->index(['linkable_type', 'linkable_id'], 'mail_links_target_idx');
            // Senkronda zincir eşleşmesi: acente + konu anahtarı
            $table->index(['agency_id', 'thread_key'], 'mail_links_agency_thread_idx');
        });

        // Zincir eşleşmesinin kesin (In-Reply-To / References) ayağı
        // mail_messages.message_id üzerinden sorgulanır; senkron sırasında
        // her yeni iletide çalıştığı için indekssiz kalması tam tablo
        // taraması demekti.
        Schema::table('mail_messages', function (Blueprint $table) {
            $table->index('message_id', 'mail_messages_message_id_idx');
        });
    }

    public function down(): void
    {
        Schema::table('mail_messages', function (Blueprint $table) {
            $table->dropIndex('mail_messages_message_id_idx');
        });

        Schema::dropIfExists('mail_links');
    }
};
