<?php

use App\Events\OrderCreated;

// PRC-622 — Tetik haritası. Bir hook/event'i şablona bağlamak = buraya satır
// eklemek; kod değişikliği gerektirmez. Closure YOK (config:cache uyumlu).
//
// Anahtar alanlar:
//   template        : communication_templates.name (zorunlu)
//   entity_type     : SendEmailJob/SendClientSmsJob entity haritası tipi (zorunlu)
//   entity_key      : hook context'inde entity ID taşıyan anahtar(lar) — ilk
//                     bulunan kullanılır, int'e cast edilir (hooks için)
//   entity_property : event üzerindeki model property adı (events için; ->id alınır)
//   fields          : ['MERGEFIELD' => 'context_anahtarı'] — yalnız scalar kopyalanır
//                     (hooks için)
//   entity_fields   : ['MERGEFIELD' => 'model.attribute.yolu'] — entity modelden
//                     dot-notation üretim (events için). Değer ARRAY ise concat:
//                     parçalar dot-notation çözülür, scalar olanlar tek boşlukla
//                     birleşir (örn ['client.first_name', 'client.last_name'])
//   setting         : ['setting_anahtarı', default] — false dönerse eşleme atlanır
//   audience        : 'client' → dispatcher admin yolunu atlar; 'admin' →
//                     email (client) yolunu atlar; yok/null → otomatik karar
//   subject_key /
//   message_key     : admin şablonlarında __() lang anahtarı; parametreler
//                     fields/entity_fields sonucundan lowercase anahtarlarla verilir
//   to_email_key    : context'te explicit alıcı e-postası anahtarı (opsiyonel)
return [
    'hooks' => [
        // Store client-area iptal talebi (ClientAreaController::storeCancellationRequest).
        // Context: userid/user_id (client id), relid/service_id (ClientProduct id),
        // reason, type (refund_type), cancellation_request_id (yeni talep id'si).
        'CancellationRequest' => [
            [
                // ADMIN bildirimi — şablon type='admin' → dispatcher admin yolu.
                'template' => 'New Cancellation Request',
                'entity_type' => 'cancellation_request',
                'entity_key' => ['cancellation_request_id'],
                'fields' => [
                    'SERVICE' => 'service_id',
                    'CLIENT' => 'user_id',
                    'REASON' => 'reason',
                ],
                'subject_key' => 'admin/cancellation-requests.notify_new_request_subject',
                'message_key' => 'admin/cancellation-requests.notify_new_request_message',
            ],
            [
                // CLIENT onay maili (type='product' satırı → SendEmailJob yolu).
                'template' => 'Cancellation Request Confirmation',
                'entity_type' => 'cancellation_request',
                'entity_key' => ['cancellation_request_id'],
                'fields' => [
                    'REASON' => 'reason',
                    'CANCELLATION_TYPE' => 'type',
                ],
            ],
        ],

        // InvoiceObserver::updated — total/total_amount/subtotal her değişimde
        // fire olur (context'te 'status' var ama mapper koşul desteklemiyor;
        // taslak/unpaid faturada da mail çıkar — bilinen kabul, Task 5 raporu).
        'UpdateInvoiceTotal' => [
            ['template' => 'Invoice Modified', 'entity_type' => 'invoice', 'entity_key' => ['invoiceid', 'invoice_id']],
        ],

        // InvoiceObserver::updated — status → refunded geçişi.
        'InvoiceRefunded' => [
            ['template' => 'Invoice Refund Confirmation', 'entity_type' => 'invoice', 'entity_key' => ['invoiceid', 'invoice_id']],
        ],

        // InvoiceObserver::updated — YALNIZ paid → unpaid geçişi (gerçek ödeme
        // reversal'ı; PRC-622 review F1). pending→unpaid oluşturma akışında
        // hook fire ETMEZ — WHMCS InvoiceUnpaid sözleşmesi bilinçli daraltıldı.
        'InvoiceUnpaid' => [
            [
                'template' => 'Payment Reversed Notification',
                'entity_type' => 'invoice',
                'entity_key' => ['invoiceid', 'invoice_id'],
                'fields' => [
                    'INVOICE_ID' => 'invoiceid',
                    'CLIENT_ID' => 'client_id',
                ],
                'subject_key' => 'admin/billing.notify_payment_reversed_subject',
                'message_key' => 'admin/billing.notify_payment_reversed_message',
            ],
        ],

        // HookServiceProvider — InvoicePaid event köprüsü (buildInvoiceContext).
        // 'Admin Payment Received Notification' yalnız admin kanallarında seed'li;
        // dispatcher admin yolu kanal-bazlı karara da bakar (Task 5 fix).
        'AddInvoicePayment' => [
            [
                'template' => 'Admin Payment Received Notification',
                'entity_type' => 'invoice',
                'entity_key' => ['invoiceid', 'invoice_id'],
                // PRC-622 review F4 — notify_admin_on_invoice_paid deseninin
                // birebiri: her tahsilatta admin bildirimi default KAPALI.
                'setting' => ['notify_admin_on_payment_received', false],
                'fields' => [
                    'INVOICE_ID' => 'invoiceid',
                    'CLIENT_ID' => 'client_id',
                ],
                'subject_key' => 'admin/billing.notify_payment_received_subject',
                'message_key' => 'admin/billing.notify_payment_received_message',
            ],
        ],

        // ── Task 6 / A2-1 — SSL + servis yaşam döngüsü ─────────────────────

        // AcmeService::issue başarı (installed=true). Context: ssl_certificate_id,
        // client_product_id/service_id, client_id, domain (common_name).
        'SSLCertificateIssued' => [
            [
                'template' => 'SSL Certificate Issued',
                'entity_type' => 'client_product',
                'entity_key' => ['client_product_id', 'service_id'],
                'fields' => ['DOMAIN' => 'domain'],
            ],
        ],

        // Reseller (manuel) SSL "müşteri girdisi bekliyor" geçişi — iki nokta:
        // AbstractSsl::createAccount (ilk satın alma) + HandleInvoiceStatusChange::
        // triggerSslRenewal (renewal sonrası installed=false flip'i).
        'SSLCertificateConfigurationRequired' => [
            [
                'template' => 'SSL Certificate Configuration Required',
                'entity_type' => 'client_product',
                'entity_key' => ['client_product_id', 'service_id'],
                'fields' => ['DOMAIN' => 'domain'],
            ],
        ],

        // HookServiceProvider bridgeLifecycleEvents — ProductProvisioningCompleted
        // (action=suspend/unsuspend) zaten fire ediyor; yalnız eşleme eklendi.
        // Context = buildServiceContext (serviceid/service_id + client_id).
        'AfterModuleSuspend' => [
            [
                'template' => 'Service Suspension',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
            ],
        ],

        'AfterModuleUnsuspend' => [
            [
                // CLIENT bildirimi (type='product' → SendEmailJob yolu).
                'template' => 'Service Unsuspension',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
            ],
            [
                // ADMIN bildirimi (type='admin' → NotificationService yolu).
                'template' => 'Service Unsuspension Successful',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
                'fields' => [
                    'SERVICE_ID' => 'service_id',
                    'CLIENT_ID' => 'client_id',
                ],
                'subject_key' => 'admin/products.notify_unsuspension_success_subject',
                'message_key' => 'admin/products.notify_unsuspension_success_message',
            ],
        ],

        'AfterModuleUnsuspendFailed' => [
            [
                'template' => 'Service Unsuspension Failed',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
                'fields' => [
                    'SERVICE_ID' => 'service_id',
                    'CLIENT_ID' => 'client_id',
                    'ERROR' => 'failureResponseMessage',
                ],
                'subject_key' => 'admin/products.notify_unsuspension_failed_subject',
                'message_key' => 'admin/products.notify_unsuspension_failed_message',
            ],
        ],

        // ProcessProductCreateJob → ProductProvisioningFailed(action=create) →
        // AfterModuleCreateFailed (HookServiceProvider). Eski custom-HTML
        // sendProvisioningFailedAdminNotification kaldırıldı (çift bildirim).
        // Double-check round: eskiden o custom maili gate'leyen mevcut UI
        // toggle'ı (email tab) buraya bağlandı — ghost setting kalmadı;
        // yetim 'product_provisioning_failed_admin' şablonu da silindi
        // (işini bu eşleme devraldı).
        // PRC-624 Task 6 — modül create BAŞARILI yolu. ProductProvisioning-
        // Completed(action=create) → AfterModuleCreate (HookServiceProvider:107,
        // buildServiceContext: service_id/client_id). 'Automatic Setup Failed'
        // ile simetrik admin uyarısı (audience='admin'). Gate: aynı toggle ailesi
        // — başarı bildirimi için ayrı setting (default kapalı; gürültü olmasın).
        'AfterModuleCreate' => [
            [
                'template' => 'Automatic Setup Successful',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
                'audience' => 'admin',
                'setting' => ['notify_product_provisioning_success_admin', false],
                'fields' => [
                    'SERVICE_ID' => 'service_id',
                    'CLIENT_ID' => 'client_id',
                ],
                'subject_key' => 'admin/products.notify_setup_success_subject',
                'message_key' => 'admin/products.notify_setup_success_message',
            ],
        ],

        'AfterModuleCreateFailed' => [
            [
                'template' => 'Automatic Setup Failed',
                'entity_type' => 'client_product',
                'entity_key' => ['service_id', 'serviceid'],
                'fields' => [
                    'SERVICE_ID' => 'service_id',
                    'CLIENT_ID' => 'client_id',
                    'ERROR' => 'failureResponseMessage',
                ],
                'subject_key' => 'admin/products.notify_setup_failed_subject',
                'message_key' => 'admin/products.notify_setup_failed_message',
            ],
        ],

        // PRC-624 Task 6 — registrar renewal BAŞARI admin uyarısı. DomainProvisioning
        // Service::handleRenewalSuccess → fireAction('DomainRenewalSuccessful',
        // buildDomainContext: domain_id/client_id + DOMAIN/EXPIRY_DATE extras).
        // 'Domain Renewed' (müşteri K2 lifecycle maili) ile AYRI: bu admin-only.
        // Gate: default kapalı (her renewal'da admin gürültüsü olmasın).
        'DomainRenewalSuccessful' => [
            [
                'template' => 'Domain Renewal Successful',
                'entity_type' => 'client_domain',
                'entity_key' => ['domain_id', 'domainid'],
                'audience' => 'admin',
                // SUBJECT/MESSAGE lang anahtarı YOK — admin kanal render'ı
                // seeded K1 şablon içeriğinden DOMAIN/EXPIRY_DATE merge'iyle gelir
                // (genel domain admin lang dosyası yok; içerik seeder'da).
                'fields' => [
                    'DOMAIN' => 'DOMAIN',
                    'EXPIRY_DATE' => 'EXPIRY_DATE',
                    'CLIENT_ID' => 'client_id',
                ],
            ],
        ],

        // ── Task 6 / A2-2 — billing & upgrade ──────────────────────────────

        // PlanChangeService::cancelExistingPending — eski unpaid upgrade
        // faturası yeni plan-değişikliği isteğinde otomatik iptal edilir.
        // PRC-622 review F2 — 'UpgradeOrderCancelled' hook'u fire etmeye devam
        // eder ama eşlemesi KALDIRILDI (hook-only): iptal Invoice status'unu
        // cancelled'a çektiği için client zaten standart 'Invoice Cancelled'
        // mailini alıyor; ayrı 'Upgrade Order Cancelled' şablonu çift mail
        // üretiyordu (şablon seeder'dan da silindi).

        // PlanChangeService::initiate — diff > 0 dalında upgrade faturası
        // yaratıldığında. Context: invoiceid + old_product/new_product/amount.
        'ProductChangeInvoiceCreated' => [
            [
                'template' => 'Product Change Invoice Created',
                'entity_type' => 'invoice',
                'entity_key' => ['invoiceid', 'invoice_id'],
                'fields' => [
                    'OLD_PRODUCT' => 'old_product',
                    'NEW_PRODUCT' => 'new_product',
                    'AMOUNT' => 'amount',
                ],
            ],
        ],

        // ProcessInvoiceBillingJob — entegratör (Gib/Logo/Parasut) hata yolu.
        // Şablon type='admin' (seeder Task 6'da düzeltildi) → admin yolu.
        'LegalInvoiceFailed' => [
            [
                'template' => 'Admin Legal Invoice Failed',
                'entity_type' => 'invoice',
                'entity_key' => ['invoiceid', 'invoice_id'],
                'fields' => [
                    'INVOICE_ID' => 'invoiceid',
                    'CLIENT_ID' => 'client_id',
                    'ERROR' => 'error',
                ],
                'subject_key' => 'admin/billing.notify_legal_invoice_failed_subject',
                'message_key' => 'admin/billing.notify_legal_invoice_failed_message',
            ],
        ],

        // ProcessAutoPayJob — kayıtlı kartla otomatik tahsilat başarısız.
        'AutoPaymentFailed' => [
            [
                'template' => 'Credit Card Payment Failed',
                'entity_type' => 'invoice',
                'entity_key' => ['invoiceid', 'invoice_id'],
                'fields' => [
                    'ERROR' => 'error',
                    'ATTEMPT' => 'attempt',
                ],
            ],
        ],

        // DueInvoiceService::generateForClient — yenileme faturası üretim
        // hatası (iç fatura-yaratma catch'i + dış catch).
        'ServiceRenewalFailed' => [
            [
                'template' => 'Service Renewal Failed',
                'entity_type' => 'client',
                'entity_key' => ['client_id', 'user_id'],
                'fields' => [
                    'CLIENT_ID' => 'client_id',
                    'ERROR' => 'error',
                ],
                'subject_key' => 'admin/billing.notify_service_renewal_failed_subject',
                'message_key' => 'admin/billing.notify_service_renewal_failed_message',
            ],
        ],

        // ── Task 6 / A2-3 — misc + affiliate ───────────────────────────────

        // PublicUnsubscribeController (kampanya subscriber'ı — client OLMAYABİLİR)
        // + Store UnsubscribeController (client marketing consent withdraw).
        // Alıcı explicit to_email_key ile; entity 'system' (SendEmailJob entity
        // yüklemez, toEmail zorunlu). entity_key yalnız log/id metadata'sı.
        'SubscriberUnsubscribed' => [
            [
                'template' => 'Unsubscribe Confirmation',
                'entity_type' => 'system',
                'entity_key' => ['subscriber_id', 'client_id'],
                'to_email_key' => 'email',
                'fields' => ['EMAIL' => 'email'],
            ],
        ],

        // CheckoutController — checkout'ta kabul edilen 'custom' tip sözleşme
        // (mesafeli satış sözleşmeleri custom tipiyle modellenir; ContractType
        // enum'unda ayrı distance-selling tipi yok). Tip filtresi fire
        // noktasında.
        'DistanceSellingContractAccepted' => [
            [
                'template' => 'Distance Selling Contract Custom',
                'entity_type' => 'order',
                'entity_key' => ['order_id', 'orderid'],
                'fields' => ['CONTRACT_TITLE' => 'contract_title'],
            ],
        ],

        // Store AffiliateController::submitActivation — yeni başvuru (ADMIN
        // bildirimi 'Admin Affiliate Application Received'; type='admin', admin
        // kanal satırları seedAdminChannels'tan zaten mevcut).
        'AffiliateApplicationReceived' => [
            [
                'template' => 'Admin Affiliate Application Received',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'CLIENT_EMAIL' => 'client_email',
                    'REFERRAL_CODE' => 'referral_code',
                ],
                'subject_key' => 'admin/affiliates.notify_application_received_subject',
                'message_key' => 'admin/affiliates.notify_application_received_message',
            ],
            [
                // PRC-624 Task 6 — CLIENT onay maili (aynı hook, ikinci satır).
                // audience='client' → dispatcher admin yolunu atlar; şablon
                // type='affiliate' channel='email' → SendEmailJob yolu.
                'template' => 'Affiliate Application Received',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'audience' => 'client',
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'CLIENT_EMAIL' => 'client_email',
                    'REFERRAL_CODE' => 'referral_code',
                ],
            ],
        ],

        // Admin AffiliateController approve/reject/suspend — client mailleri.
        // ('Affiliate Account Activated' yalnız store başvuru anında dispatch ediliyor,
        // approve'da değil — çift mail yok.) PRC-622 review F8 —
        // 'audience' => 'client': işlemi zaten admin kendisi yapıyor; şablonların
        // admin-kanal satırları legacy'dir ve SUBJECT/MESSAGE'sız boş admin
        // bildirimi üretiyordu. Dispatcher admin yolunu atlar.
        'AffiliateApproved' => [
            [
                'template' => 'Affiliate Approved',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'audience' => 'client',
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'REFERRAL_CODE' => 'referral_code',
                    'COMMISSION_RATE' => 'commission_rate',
                ],
            ],
        ],

        'AffiliateRejected' => [
            [
                'template' => 'Affiliate Rejected',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'audience' => 'client',
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'REASON' => 'reason',
                ],
            ],
        ],

        'AffiliateSuspended' => [
            [
                'template' => 'Affiliate Suspended',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'audience' => 'client',
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'REASON' => 'reason',
                ],
            ],
        ],

        // ── Task 9 / Dalga A ───────────────────────────────────────────────

        // Store AffiliateController::submitActivation — CLIENT "ortaklık
        // aktifleştirildi" maili. Eski doğrudan SendEmailJob çağrısı 'affiliate'
        // entity tipiyle KIRIKTI (SendEmailJob haritasında yok); Task 9'da
        // hook + bu eşlemeyle değiştirildi. Şablon type='affiliate'
        // channel='email' → dispatcher email yolu; entity 'client' → alıcı
        // client'ın kendisi (template default içeriği {FIRSTNAME}/{LASTNAME}
        // placeholder'larını client entity'den alır).
        'AffiliateActivation' => [
            [
                'template' => 'Affiliate Account Activated',
                'entity_type' => 'client',
                'entity_key' => ['client_id'],
                'fields' => [
                    'CLIENT_NAME' => 'client_name',
                    'CLIENT_EMAIL' => 'client_email',
                    'REFERRAL_CODE' => 'referral_code',
                ],
            ],
        ],

        // PRC-775 — DomainLifecycleService::handleTransferOut → fireAction
        // ('DomainTransferred', ctx). Tek olay iki hedefe fan-out: admin uyarısı
        // + müşteri bildirimi (madde-117). audience gate ile çift-fire yok.
        'DomainTransferred' => [
            [
                // ADMIN uyarısı (fatura iptali/credit-note + transfer bilgisi)
                'template' => 'Admin Domain Transferred Away',
                'entity_type' => 'client_domain',
                'entity_key' => ['domain_id'],
                'audience' => 'admin',
                'fields' => [
                    'DOMAIN_NAME' => 'domain_name',
                    'CLIENT_ID' => 'client_id',
                    'ACTION_TAKEN' => 'action_taken',
                ],
                'subject_key' => 'admin/domains.notify_transferred_subject',
                'message_key' => 'admin/domains.notify_transferred_message',
            ],
            [
                // MÜŞTERİ bildirimi (transfer çıkışı — bağlı hizmetlerini gözden geçir)
                'template' => 'Domain Transferred Away Notification',
                'entity_type' => 'client_domain',
                'entity_key' => ['domain_id'],
                'audience' => 'client',
                'fields' => [
                    'DOMAIN_NAME' => 'domain_name',
                    'TRANSFER_DATE' => 'transfer_date',
                ],
            ],
        ],
    ],

    'events' => [
        // PRC-621 → PRC-622: yeni sipariş admin bildirimi (eski
        // SendOrderCreatedNotification listener'ının config karşılığı).
        OrderCreated::class => [
            [
                'template' => 'New Order Notification',
                'entity_type' => 'order',
                'entity_property' => 'order',
                'setting' => ['enable_admin_order_notifications', true],
                'entity_fields' => [
                    'ORDER_NUMBER' => 'order_number',
                    'CLIENT_NAME' => ['client.first_name', 'client.last_name'],
                    // Order.total decimal:2 cast — string zaten 2 hane.
                    'TOTAL' => ['total', 'currency.code'],
                ],
                'subject_key' => 'admin/orders.notify_admin_order_created_subject',
                'message_key' => 'admin/orders.notify_admin_order_created_message',
            ],
        ],
    ],
];
