<?php

namespace App\Support;

/**
 * PRC-625 — Kanonik merge field sözlüğü + geriye-uyumlu dual-emit.
 *
 * Projede tarihsel olarak ÜÇ ad stili birikti:
 *   1. ClientMergeFieldBuilder: underscore'suz primary (INVOICENUM, TICKETID,
 *      CLIENTID, ORDERID, DOMAINNAME) + bazı legacy underscore'lu.
 *   2. EmailTemplateHelper / NotificationTemplateService sistem field'ları:
 *      underscore'lu (CLIENT_ID, INVOICE_NUMBER, TICKET_ID).
 *   3. Seeder içerikleri: karışık (PRC-625 sonrası YALNIZ kanonik underscore).
 *
 * `expand()` her field için HEM kanonik underscore HEM legacy underscore'suz
 * adı doldurur → hangi stildeki içerik olursa olsun değer basar; mevcut custom
 * içerik KIRILMAZ. Bu geriye-uyumlu bir GENİŞLETME'dir; hiçbir adı silmez,
 * var olan anahtarı EZMEZ (yalnız eksik yönü tamamlar).
 *
 * KRİTİK: ID ≠ NUMBER. INVOICEID/$invoice->id ile INVOICENUM/$invoice->invoice_number
 * AYRI kavramlar; alias'larında BİRLEŞTİRİLMEZ (her biri kendi underscore çiftini
 * alır). Aynısı ORDERID($order->id) vs ORDERNUMBER($order->order_number) için.
 */
class MergeFieldDictionary
{
    /**
     * Spec §3.1 kanonik underscore adları (referans + dokümantasyon).
     */
    public const CANONICAL = [
        'CLIENT_NAME', 'FIRSTNAME', 'LASTNAME', 'EMAIL', 'COMPANY_NAME', 'SITE_URL',
        'SIGNATURE', 'CURRENT_DATE', 'INVOICE_NUMBER', 'INVOICE_TOTAL', 'DUE_DATE',
        'INVOICE_URL', 'PAYMENT_METHOD', 'AMOUNT', 'CURRENCY', 'ORDER_NUMBER',
        'ORDER_TOTAL', 'ORDER_URL', 'TICKET_ID', 'TICKET_SUBJECT', 'TICKET_DEPARTMENT',
        'TICKET_URL', 'DOMAIN_NAME', 'EXPIRY_DATE', 'NAMESERVERS', 'SERVICE_NAME',
        'SERVICE_DOMAIN', 'NEXT_DUE_DATE', 'QUOTE_NUMBER', 'QUOTE_TOTAL', 'QUOTE_URL',
        'COMMISSION_AMOUNT', 'PAYOUT_AMOUNT', 'STATUS', 'REASON', 'SUBJECT', 'MESSAGE',
    ];

    /**
     * Legacy (underscore'suz / alternatif) ad → kanonik (underscore'lu) ad.
     *
     * expand() çift yönlü çalışır: bir alias varsa kanonik'i, kanonik varsa
     * TÜM alias'larını doldurur. Bu yüzden burada yalnız "alias → kanonik"
     * tek yönü tanımlanır; ters yön türetilir.
     *
     * KURAL: yalnız GERÇEKTEN AYNI KAVRAM eşlenir. ID ve NUMBER ayrı kavram
     * olduğundan ayrı çiftlerde tutulur (INVOICEID→INVOICE_ID, INVOICENUM→
     * INVOICE_NUMBER; ORDERID→ORDER_ID, ORDERNUMBER→ORDER_NUMBER).
     */
    public const ALIASES = [
        // --- Client ---
        'CLIENTID' => 'CLIENT_ID',
        'CLIENTEMAIL' => 'CLIENT_EMAIL',
        'COMPANY' => 'COMPANY_NAME',
        'COMPANYNAME' => 'COMPANY_NAME',
        'FIRST_NAME' => 'FIRSTNAME',
        'LAST_NAME' => 'LASTNAME',

        // --- Invoice (ID ≠ NUMBER) ---
        'INVOICEID' => 'INVOICE_ID',
        'INVOICENUM' => 'INVOICE_NUMBER',
        'INVOICENUMBER' => 'INVOICE_NUMBER',
        'INVOICE_NUM' => 'INVOICE_NUMBER',
        'INVOICEDATE' => 'INVOICE_DATE',
        'INVOICETOTAL' => 'INVOICE_TOTAL',
        'INVOICESTATUS' => 'INVOICE_STATUS',
        'INVOICEURL' => 'INVOICE_URL',
        'DUEDATE' => 'DUE_DATE',
        'RECEIPTURL' => 'RECEIPT_URL',
        'PAYMENTDATE' => 'PAYMENT_DATE',
        'PAYMENTMETHOD' => 'PAYMENT_METHOD',
        'PAYMENTAMOUNT' => 'PAYMENT_AMOUNT',

        // --- Order (ID ≠ NUMBER) ---
        'ORDERID' => 'ORDER_ID',
        'ORDERNUMBER' => 'ORDER_NUMBER',
        'ORDERDATE' => 'ORDER_DATE',
        'ORDERTOTAL' => 'ORDER_TOTAL',
        'ORDERSTATUS' => 'ORDER_STATUS',
        'ORDERURL' => 'ORDER_URL',

        // --- Ticket (TICKETID kanonik TICKET_ID'dir) ---
        'TICKETID' => 'TICKET_ID',
        'TICKETNUMBER' => 'TICKET_NUMBER',
        'TICKETSUBJECT' => 'TICKET_SUBJECT',
        'TICKETSTATUS' => 'TICKET_STATUS',
        'TICKETPRIORITY' => 'TICKET_PRIORITY',
        'TICKETDEPARTMENT' => 'TICKET_DEPARTMENT',
        'TICKETURL' => 'TICKET_URL',
        'TICKETMESSAGE' => 'TICKET_MESSAGE',

        // --- Domain ---
        'DOMAINID' => 'DOMAIN_ID',
        'DOMAINNAME' => 'DOMAIN_NAME',
        'DOMAINTLD' => 'DOMAIN_TLD',
        'DOMAINSTATUS' => 'DOMAIN_STATUS',
        'DOMAINURL' => 'DOMAIN_URL',
        'DOMAINEXPIRYDATE' => 'DOMAIN_EXPIRY_DATE',
        'DOMAINREGISTRATIONDATE' => 'DOMAIN_REGISTRATION_DATE',
        'EXPIRYDATE' => 'EXPIRY_DATE',
        'REGISTRATIONDATE' => 'REGISTRATION_DATE',
        'RENEWALDATE' => 'RENEWAL_DATE',
        'NEWEXPIRYDATE' => 'NEW_EXPIRY_DATE',
        'RENEWALPERIOD' => 'RENEWAL_PERIOD',

        // --- Verification / auth ---
        'VERIFICATIONCODE' => 'VERIFICATION_CODE',
        'VERIFICATIONURL' => 'VERIFICATION_URL',
        'EXPIRESMINUTES' => 'EXPIRES_MINUTES',
        'EXPIRESAT' => 'EXPIRES_AT',
        'RESETCODE' => 'RESET_CODE',
        'RESETURL' => 'RESET_URL',
        'INVITELINK' => 'INVITE_LINK',

        // --- Service / misc ---
        'SERVICENAME' => 'SERVICE_NAME',
        'BONUSAMOUNT' => 'BONUS_AMOUNT',
        'MAINTENANCETIME' => 'MAINTENANCE_TIME',
        'ALERTMESSAGE' => 'ALERT_MESSAGE',
        'ALERTTYPE' => 'ALERT_TYPE',
        'BILLINGURL' => 'BILLING_URL',
        'CARDEXPIRY' => 'CARD_EXPIRY',

        // --- SSL ---
        'SSLSTARTDATE' => 'SSL_START_DATE',
        'SSLENDDATE' => 'SSL_END_DATE',
        'SSLTYPE' => 'SSL_TYPE',

        // --- cPanel ---
        'CPANELUSERNAME' => 'CPANEL_USERNAME',
        'CPANELPASSWORD' => 'CPANEL_PASSWORD',
        'CPANELURL' => 'CPANEL_URL',

        // --- Cancellation ---
        'CANCELLATIONID' => 'CANCELLATION_ID',
        'CANCELLATIONREASON' => 'CANCELLATION_REASON',
        'REQUESTDATE' => 'REQUEST_DATE',

        // --- Admin / reply ---
        'ADMINNAME' => 'ADMIN_NAME',
        'ADMINEMAIL' => 'ADMIN_EMAIL',
        'ADMINORDERURL' => 'ADMIN_ORDER_URL',
        'ADMINCANCELLATIONURL' => 'ADMIN_CANCELLATION_URL',
        'REPLYID' => 'REPLY_ID',
        'REPLYDATE' => 'REPLY_DATE',
        'REPLYTIME' => 'REPLY_TIME',
    ];

    /**
     * Her field için hem kanonik hem legacy adı doldurur.
     *
     * Çift yönlü: legacy alias varsa kanonik'i ekler; kanonik varsa o kanonik'e
     * eşlenen TÜM legacy alias'ları ekler. Var olan bir anahtarı ASLA ezmez —
     * yalnız eksik yönü tamamlar (custom içerik + override güvenli).
     */
    public static function expand(array $fields): array
    {
        // Kanonik → [alias, ...] ters haritası (lazy, statik)
        static $reverse = null;
        if ($reverse === null) {
            $reverse = [];
            foreach (self::ALIASES as $alias => $canonical) {
                $reverse[$canonical][] = $alias;
            }
        }

        $expanded = $fields;

        foreach ($fields as $key => $value) {
            // 1) alias verildiyse → kanonik'i tamamla
            if (isset(self::ALIASES[$key])) {
                $canonical = self::ALIASES[$key];
                if (! array_key_exists($canonical, $expanded)) {
                    $expanded[$canonical] = $value;
                }
            }

            // 2) kanonik verildiyse → tüm alias'ları tamamla
            if (isset($reverse[$key])) {
                foreach ($reverse[$key] as $alias) {
                    if (! array_key_exists($alias, $expanded)) {
                        $expanded[$alias] = $value;
                    }
                }
            }
        }

        return $expanded;
    }
}
