<?php

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

/**
 * Ödemeler defteri — acentenin tüm para hareketleri.
 *
 * Tek tablo hem tahsilatı (müşteriden gelen) hem de gideri (tedarikçiye,
 * personele yapılan) tutar; `direction` ayırır. Daha önce ödeme yalnızca
 * `sales.paid_amount` üzerinde toplam bir sayıydı; artık her hareket
 * tarihi, yöntemi, kanalı ve dekontuyla ayrı bir kayıttır.
 *
 * İlişkilendirme üç katmanlı:
 *   sale_id     → tahsilatın hangi satışa sayılacağı (sıcak yol, doğrudan FK)
 *   invoice_id  → hangi faturayı kapattığı (fatura "ödendi" olur)
 *   payable_*   → diğer her şey (kaynak ataması/tedarikçi işi vb.)
 * Karşı taraf (kimden alındı / kime ödendi) `counterparty_*` polimorfik
 * bağıyla müşteri, tedarikçi veya personele bağlanır; sistemde kaydı
 * olmayan taraflar için ad alanı serbest metin olarak saklanır.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('payments', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('agency_id');
            $table->string('code', 20)->nullable();          // acente bazlı sıra no

            $table->enum('direction', ['in', 'out'])->default('in');   // in: tahsilat, out: ödeme
            $table->string('status', 20)->default('completed');        // completed/pending/failed/cancelled/refunded
            $table->string('method', 30)->default('cash');             // cash/bank_transfer/virtual_pos/pos/credit_card/cheque/promissory_note/online/offset/other
            $table->string('provider', 60)->nullable();                // sanal pos/banka/kanal adı (iyzico, Garanti…)
            $table->string('category', 40)->nullable();                // gider/gelir sınıfı (tedarikçi, komisyon, personel…)

            // Tutar — kur anı kaydedilir ki geçmiş rapor değişmesin
            $table->decimal('amount', 14, 2)->default(0);
            $table->char('currency', 3)->default('TRY');
            $table->decimal('exchange_rate', 14, 6)->default(1);
            $table->decimal('base_amount', 14, 2)->default(0);          // acente baz para biriminde karşılığı
            $table->decimal('fee_amount', 14, 2)->default(0);           // komisyon/masraf
            $table->decimal('net_amount', 14, 2)->default(0);           // amount - fee

            $table->dateTime('paid_at')->nullable();                    // gerçekleşme anı
            $table->date('due_date')->nullable();                       // planlanan (status=pending) tarih

            // İlişkiler
            $table->unsignedBigInteger('sale_id')->nullable();
            $table->unsignedBigInteger('invoice_id')->nullable();
            $table->string('payable_type')->nullable();
            $table->unsignedBigInteger('payable_id')->nullable();

            // Karşı taraf: müşteri / tedarikçi / personel ya da serbest metin
            $table->string('counterparty_type')->nullable();
            $table->unsignedBigInteger('counterparty_id')->nullable();
            $table->string('counterparty_name')->nullable();

            // Ödeme aracı ayrıntıları
            $table->string('reference_no', 80)->nullable();             // dekont/işlem/makbuz no
            $table->string('bank_account', 120)->nullable();            // acente banka hesabı (etiket/IBAN anlık kopyası)
            $table->string('card_last_four', 4)->nullable();
            $table->string('card_brand', 30)->nullable();
            $table->unsignedTinyInteger('installments')->nullable();    // taksit sayısı
            $table->dateTime('cheque_due_date')->nullable();            // çek/senet vadesi

            $table->string('description')->nullable();
            $table->text('notes')->nullable();

            $table->unsignedBigInteger('received_by')->nullable();      // tahsilatı alan / ödemeyi yapan personel
            $table->unsignedBigInteger('created_by')->nullable();
            $table->unsignedBigInteger('updated_by')->nullable();

            $table->timestamps();
            $table->softDeletes();

            $table->foreign('agency_id')->references('id')->on('agencies')->onDelete('cascade');
            $table->foreign('sale_id')->references('id')->on('sales')->nullOnDelete();
            $table->foreign('invoice_id')->references('id')->on('sale_invoices')->nullOnDelete();

            $table->index(['agency_id', 'paid_at']);
            $table->index(['agency_id', 'direction', 'status']);
            $table->index(['agency_id', 'method']);
            $table->index(['sale_id', 'status']);
            $table->index(['invoice_id', 'status']);
            $table->index(['counterparty_type', 'counterparty_id'], 'payments_counterparty_idx');
            $table->index(['payable_type', 'payable_id'], 'payments_payable_idx');
            $table->index(['agency_id', 'due_date']);
        });
    }

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