<?php

namespace App\Services\Task;

/**
 * Otomatik görev tetikleyici kataloğu (kod-tanımlı).
 *
 * kind:
 *  - event     → domain olayı anında tetiklenir (servis/model kancaları)
 *  - scheduled → tasks:scan-triggers komutu tarafından periyodik taranır
 *
 * v2 adayları (bilinçli olarak kapsam dışı): kaynak sözleşmesi imzalanmadı,
 * kaynak çakışması, tedarikçi fiyat listesi yenileme, müşteri doğum günü.
 */
class TaskTriggerCatalog
{
    public const GROUPS = [
        'operasyon' => 'Operasyon',
        'satis' => 'Satış',
        'odeme' => 'Ödeme',
        'takip' => 'Takip',
        'fatura' => 'Fatura',
    ];

    private const TRIGGERS = [
        // ================= OPERASYON =================
        'deadline_missed_min_pax' => [
            'group' => 'operasyon',
            'label' => 'Kayıt süresi doldu, min. katılımcı sağlanamadı',
            'description' => 'Bir tur kalkışının son rezervasyon tarihi geçtiği halde minimum katılımcı sayısına ulaşılamadığında oluşur. Tur tarihinin iptali/ertelenmesi değerlendirilmelidir.',
            'when' => 'Periyodik taramada çalışır: kalkışın son rezervasyon tarihi (kayıt bitiş kuralı) geçmiş, kalkış hâlâ kesinleşmemiş ve dolu koltuk (satılan+rezerve) minimum katılımcının altındaysa görev oluşur. Kalkış başına ömür boyu bir kez üretilir.',
            'title_template' => 'Tur tarihini kontrol ediniz: {{tur.ad}} ({{kalkis.tarih}}) — kayıt bitiş süresi doldu, min. katılımcı sağlanamadı ({{kalkis.dolu}}/{{kalkis.min_katilimci}})',
            'kind' => 'scheduled',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Kalkışın doluluk ve rezervasyon durumunu kontrol et',
                'Yönetimle iptal / erteleme kararını netleştir',
                'Karara göre kalkışı iptal et veya tarihini güncelle',
                'Rezervasyonlu müşterileri bilgilendir',
            ],
        ],
        'departure_guaranteed' => [
            'group' => 'operasyon',
            'label' => 'Kesin kalkışa geçti',
            'description' => 'Bir kalkış (otomatik eşikle veya manuel olarak) kesin kalkış durumuna geçtiğinde oluşur. Operasyon hazırlıkları (konaklama, ulaşım, rehber) başlatılmalıdır.',
            'when' => 'Olay anında çalışır: kalkış, minimum katılımcıya ulaşıp otomatik eşikle kesinleştiği veya operasyon ekranından manuel "kesin kalkış" yapıldığı an görev oluşur. Kalkış başına bir kez üretilir.',
            'title_template' => 'Kesin kalkış: {{tur.ad}} ({{kalkis.tarih}}) — operasyon hazırlıklarını başlatın ({{tetik.mod}})',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 48,
            'default_checklist' => [
                'Konaklama rezervasyonlarını teyit et',
                'Ulaşım / araç planını netleştir',
                'Rehber ve kaptan atamalarını yap',
                'Yemek organizasyonunu teyit et',
                'Müşterilere kesin kalkış bilgilendirmesi gönder',
            ],
        ],
        'guarantee_deadline_near' => [
            'group' => 'operasyon',
            'label' => 'Kesinleşme tarihi yaklaşıyor',
            'description' => 'Kalkışın kesinleşme (garanti) son tarihine 48 saatten az kaldığı halde kalkış hâlâ kesinleşmediğinde oluşur.',
            'when' => 'Periyodik taramada çalışır: kalkışın kesinleşme son tarihine 48 saatten az kalmış ve kalkış hâlâ kesinleşmemişse görev oluşur. Kalkış başına bir kez üretilir.',
            'title_template' => 'Kesinleşme tarihi yaklaşıyor: {{tur.ad}} ({{kalkis.tarih}}) — kalkış hâlâ kesinleşmedi',
            'kind' => 'scheduled',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Doluluk ve minimum katılımcı durumunu kontrol et',
                'Satış ekibiyle son satış fırsatlarını değerlendir',
                'Kesinleştirme veya iptal kararını ver ve uygula',
            ],
        ],
        'departure_prep_incomplete' => [
            'group' => 'operasyon',
            'label' => 'Kalkış yaklaşıyor, operasyon onayları eksik',
            'description' => 'Kalkışa 7 günden az kaldığı halde konaklama / yemek / ulaşım onaylarından en az biri tamamlanmadığında oluşur.',
            'when' => 'Periyodik taramada çalışır: kalkışa 7 günden az kalmış, satış yapılmış ve konaklama/yemek/ulaşım onaylarından en az biri eksikse görev oluşur. Kalkış başına bir kez üretilir.',
            'title_template' => 'Kalkış yaklaşıyor: {{tur.ad}} ({{kalkis.tarih}}) — eksik operasyonel onaylar: {{tetik.eksikler}}',
            'kind' => 'scheduled',
            'default_priority' => 'urgent',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Eksik onayları listele (konaklama / yemek / ulaşım)',
                'İlgili tedarikçilerden yazılı teyit al',
                'Operasyon ekranında hizmet onaylarını işaretle',
            ],
        ],
        'departure_completed' => [
            'group' => 'operasyon',
            'label' => 'Tur tamamlandı',
            'description' => 'Bir kalkış tamamlandı olarak işaretlendiğinde oluşur. Tur sonrası işlemler (geri bildirim, tedarikçi mutabakatı) yürütülmelidir.',
            'when' => 'Olay anında çalışır: kalkış, operasyon ekranından "tamamlandı" olarak işaretlendiği an görev oluşur. Kalkış başına bir kez üretilir.',
            'title_template' => 'Tur tamamlandı: {{tur.ad}} ({{kalkis.tarih}}) — tur sonrası işlemleri yürütün',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 72,
            'default_checklist' => [
                'Müşteri geri bildirimlerini topla',
                'Tedarikçi mutabakatlarını yap',
                'Kaynak (rehber / araç) ödemelerini kontrol et',
                'Tur kapanış raporunu tamamla',
            ],
        ],
        'departure_cancelled' => [
            'group' => 'operasyon',
            'label' => 'Tur iptal edildi',
            'description' => 'Bir kalkış iptal edildiğinde oluşur. Rezervasyonlu müşteriler bilgilendirilmeli, iade süreçleri başlatılmalıdır.',
            'when' => 'Olay anında çalışır: kalkış, operasyon ekranından iptal edildiği an görev oluşur. Kalkış başına bir kez üretilir.',
            'title_template' => 'Tur iptal edildi: {{tur.ad}} ({{kalkis.tarih}}) — müşterileri bilgilendirin, iade süreçlerini başlatın',
            'kind' => 'event',
            'default_priority' => 'urgent',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Rezervasyonlu müşterileri arayarak bilgilendir',
                'İade süreçlerini başlat',
                'Tedarikçi rezervasyonlarını iptal et',
                'Kaynak atamalarını kaldır',
            ],
        ],

        // ================= SATIŞ =================
        'sale_created' => [
            'group' => 'satis',
            'label' => 'Yeni rezervasyon oluştu',
            'description' => 'Yeni bir rezervasyon/satış kaydı oluştuğunda oluşur (anlık taslaklar hariç).',
            'when' => 'Olay anında çalışır: yeni satış kaydı taslak (potansiyel) DIŞINDA bir durumla kaydedildiği an; veya bir taslak teklif/rezervasyon gibi gerçek bir duruma dönüştüğü an görev oluşur. Taslak doğrudan onaylanır/iptal edilirse bu tetikleyici atlanır (onun yerine ilgili tetikleyici çalışır). Satış başına bir kez üretilir.',
            'title_template' => 'Yeni rezervasyon: {{satis.kod}} — {{musteri.ad_soyad}} kaydını kontrol edin',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Rezervasyon bilgilerini (tarih, kişi sayısı, tutar) kontrol et',
                'Müşteri iletişim bilgilerini doğrula',
                'Ödeme planını netleştir ve kaydet',
            ],
        ],
        'sale_confirmed' => [
            'group' => 'satis',
            'label' => 'Rezervasyon onaylandı',
            'description' => 'Bir satış onaylandı durumuna geçtiğinde oluşur. Belge hazırlıkları yapılmalıdır.',
            'when' => 'Olay anında çalışır: satışın durumu hangi ekrandan olursa olsun "Onaylandı"ya geçtiği an görev oluşur. Satış başına bir kez üretilir.',
            'title_template' => 'Rezervasyon onaylandı: {{satis.kod}} — belge hazırlığını yapın',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 48,
            'default_checklist' => [
                'Sözleşme / voucher belgelerini hazırla',
                'Müşteriye onay ve belgeleri gönder',
                'Ödeme planı ve tahsilat durumunu kontrol et',
            ],
        ],
        'sale_cancelled' => [
            'group' => 'satis',
            'label' => 'Rezervasyon iptal edildi',
            'description' => 'Bir satış iptal edildiğinde oluşur. İade ve müşteri bilgilendirme işlemleri yürütülmelidir.',
            'when' => 'Olay anında çalışır: satışın durumu "İptal"e geçtiği an görev oluşur. Satış başına bir kez üretilir.',
            'title_template' => 'Rezervasyon iptal edildi: {{satis.kod}} — iade ve bilgilendirme işlemlerini yürütün',
            'kind' => 'event',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'İptal koşullarını ve kesinti tutarını hesapla',
                'İade işlemini başlat',
                'Müşteriye iptal teyidi gönder',
            ],
        ],
        'offer_stale' => [
            'group' => 'satis',
            'label' => 'Teklif yanıtsız kaldı',
            'description' => 'Gönderilen bir teklif 3 günden uzun süredir yanıtsız kaldığında oluşur. Müşteri aranmalıdır.',
            'when' => 'Periyodik taramada çalışır: "Teklif Verildi" durumundaki satış 3 günden uzun süredir hiç güncellenmemişse görev oluşur. Satış başına bir kez üretilir.',
            'title_template' => 'Teklif yanıtsız: {{satis.kod}} — {{tetik.gun}} gündür yanıt alınamadı, müşteriyi arayın',
            'kind' => 'scheduled',
            'default_priority' => 'normal',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Müşteriyi telefonla ara',
                'Gerekliyse teklifi güncelle / revize et',
                'Görüşme sonucunu satış kaydına işle',
            ],
        ],

        // ================= ÖDEME =================
        'departure_soon_unpaid' => [
            'group' => 'odeme',
            'label' => 'Kalkış yaklaşıyor, ödeme eksik',
            'description' => 'Kalkışa 7 günden az kalan satışta hâlâ ödenmemiş bakiye olduğunda oluşur.',
            'when' => 'Periyodik taramada çalışır: satışın başlangıç tarihine 7 günden az kalmış, satış kesinleşmiş (onaylı/devam eden) ve ödenmemiş bakiye varsa görev oluşur. Satış başına bir kez üretilir.',
            'title_template' => 'Kalkış yaklaşıyor, ödeme eksik: {{satis.kod}} — kalan {{satis.kalan}} {{satis.para_birimi}}',
            'kind' => 'scheduled',
            'default_priority' => 'urgent',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Kalan bakiyeyi ve vade tarihini kontrol et',
                'Müşteriyle iletişime geç, ödeme talep et',
                'Ödeme alınamadıysa yönetimle iptal kararını değerlendir',
            ],
        ],
        'payment_deadline_missed' => [
            'group' => 'odeme',
            'label' => 'Ödeme tarihi geçti',
            'description' => 'Kapora veya bakiye ödeme son tarihi geçtiği halde ödeme tamamlanmadığında oluşur.',
            'when' => 'Periyodik taramada çalışır: kalkışın kapora son tarihi geçmiş ve satışta hiç ödeme yoksa; veya bakiye son tarihi geçmiş ve ödeme tamamlanmamışsa görev oluşur. Satış başına, vade türü (kapora/bakiye) başına bir kez üretilir.',
            'title_template' => 'Ödeme tarihi geçti: {{satis.kod}} — {{tetik.vade_turu}} aşıldı, bakiye {{satis.kalan}} {{satis.para_birimi}}',
            'kind' => 'scheduled',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Müşteriyi geciken ödeme için ara',
                'Yeni ödeme tarihi belirle veya iptal sürecini başlat',
                'Sonucu satış kaydına işle',
            ],
        ],
        'payment_received' => [
            'group' => 'odeme',
            'label' => 'Ödeme alındı',
            'description' => 'Bir satışa ödeme kaydedildiğinde oluşur. Makbuz/onay gönderimi yapılmalıdır.',
            'when' => 'Olay anında çalışır: satışa ödeme kaydedildiği an görev oluşur. Diğerlerinden farklı olarak HER ödeme için ayrı görev üretilir.',
            'title_template' => 'Ödeme alındı: {{satis.kod}} — {{tetik.tutar}} {{satis.para_birimi}} işlendi{{tetik.tamami}}',
            'kind' => 'event',
            'default_priority' => 'low',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Ödemeyi muhasebe kaydıyla eşleştir',
                'Müşteriye makbuz / onay gönder',
            ],
        ],

        // ================= TAKİP =================
        'task_overdue_escalation' => [
            'group' => 'takip',
            'label' => 'Geciken görev bildirimi',
            'description' => 'Bir görev, son tarihinden 1 günden uzun süredir tamamlanmadığında yöneticiye eskalasyon görevi oluşur.',
            'when' => 'Periyodik taramada çalışır: açık (bekleyen/devam eden) bir görev, son tarihinden 1 günden uzun süredir gecikmiş ve arşivlenmemişse görev oluşur. Geciken görev başına bir kez üretilir.',
            'title_template' => 'Geciken görev: "{{gorev.baslik}}" — {{tetik.gun}} gündür gecikmiş',
            'kind' => 'scheduled',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Geciken görevi ve sorumlusunu incele',
                'Sorumluyla görüş, engeli tespit et',
                'Görevi yeniden planla veya başka birine devret',
            ],
        ],
        'passport_expiring' => [
            'group' => 'takip',
            'label' => 'Pasaport geçerliliği yetersiz',
            'description' => 'Önümüzdeki 45 gün içinde kalkışı olan kesinleşmiş satışlarda, müşterinin pasaport geçerlilik süresi kalkış tarihinden itibaren 6 aydan az olduğunda oluşur.',
            'when' => 'Periyodik taramada çalışır: önümüzdeki 45 gün içinde başlayan kesinleşmiş satışın müşterisinin pasaport geçerliliği, kalkış tarihi + 6 aydan önce doluyorsa görev oluşur. Satış başına bir kez üretilir.',
            'title_template' => 'Pasaport geçerliliği yetersiz: {{musteri.ad_soyad}} — {{tur.ad}} kalkışından önce süresi doluyor',
            'kind' => 'scheduled',
            'default_priority' => 'high',
            'due_offset_hours' => 72,
            'default_checklist' => [
                'Müşteriyi pasaport geçerliliği konusunda bilgilendir',
                'Pasaport yenileme sürecini takip et',
                'Gerekirse rezervasyon / vize planını güncelle',
            ],
        ],

        // ================= FATURA =================
        'invoice_created' => [
            'group' => 'fatura',
            'label' => 'Fatura oluşturuldu',
            'description' => 'Sistemde yeni bir fatura oluşturulduğunda oluşur. Resmi faturanın (GİB/e-Arşiv) kesilmesi ve muhatap bilgilerinin kontrolü takip edilmelidir.',
            'when' => 'Olay anında çalışır: genel faturalar veya satış ekranından yeni bir fatura kaydedildiği an görev oluşur. Fatura başına bir kez üretilir.',
            'title_template' => 'Yeni fatura: {{fatura.no}} — {{fatura.muhatap}} ({{fatura.tutar}} {{fatura.para_birimi}}) resmi fatura kesimini takip edin',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Muhatap (unvan / TC / vergi no) bilgilerini kontrol et',
                'Kalem tutarlarını ve KDV oranlarını doğrula',
                'Resmi faturayı (e-Arşiv/GİB) kes',
                'Faturayı müşteriye ilet',
            ],
        ],
        'invoice_official_issued' => [
            'group' => 'fatura',
            'label' => 'Resmi fatura kesildi',
            'description' => 'Bir faturanın resmi (GİB/e-Arşiv) kesimi tamamlandığında oluşur. Faturanın müşteriye iletilmesi ve muhasebe kaydı yürütülmelidir.',
            'when' => 'Olay anında çalışır: faturanın resmi fatura durumu "Kesildi" olarak işaretlendiği an görev oluşur. Fatura başına bir kez üretilir.',
            'title_template' => 'Resmi fatura kesildi: {{fatura.no}} — {{fatura.muhatap}} · faturayı müşteriye iletin',
            'kind' => 'event',
            'default_priority' => 'normal',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Resmi faturayı müşteriye e-posta ile gönder',
                'Muhasebe / ön muhasebe kaydını işle',
                'Tahsilat durumunu kontrol et',
            ],
        ],
        'invoice_cancelled' => [
            'group' => 'fatura',
            'label' => 'Fatura iptal edildi',
            'description' => 'Bir fatura iptal edildiğinde oluşur. Resmi fatura kesildiyse iptal/iade faturası süreci yürütülmeli, müşteri bilgilendirilmelidir.',
            'when' => 'Olay anında çalışır: faturanın durumu veya resmi fatura durumu "İptal"e çekildiği an görev oluşur. Fatura başına bir kez üretilir.',
            'title_template' => 'Fatura iptal edildi: {{fatura.no}} — {{fatura.muhatap}} · iptal/iade sürecini yürütün',
            'kind' => 'event',
            'default_priority' => 'high',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Resmi fatura kesildiyse iptal / iade faturası düzenle',
                'Müşteriyi iptal hakkında bilgilendir',
                'Muhasebe kaydını düzelt',
            ],
        ],
        'invoice_official_pending_stale' => [
            'group' => 'fatura',
            'label' => 'Resmi fatura beklemede kaldı',
            'description' => 'Kesilmiş bir faturanın resmi (GİB/e-Arşiv) kesimi 3 günden uzun süredir beklemede olduğunda oluşur. Yasal süreler aşılmadan resmi fatura kesilmelidir.',
            'when' => 'Periyodik taramada çalışır: durumu "Kesildi" veya "Ödendi" olan bir faturanın resmi fatura durumu, kesim tarihinden itibaren 3 günden uzun süredir "Bekliyor" ise görev oluşur. Fatura başına bir kez üretilir.',
            'title_template' => 'Resmi fatura bekliyor: {{fatura.no}} — {{fatura.muhatap}} · {{tetik.gun}} gündür resmi fatura kesilmedi!',
            'kind' => 'scheduled',
            'default_priority' => 'urgent',
            'due_offset_hours' => 24,
            'default_checklist' => [
                'Faturanın muhatap ve tutar bilgilerini son kez kontrol et',
                'Resmi faturayı (e-Arşiv/GİB) kes',
                'Sistemde resmi fatura durumunu "Kesildi" olarak işaretle',
            ],
        ],
    ];

    /** @return array<string, array> key => tanım (key alanı dahil) */
    public static function all(): array
    {
        $out = [];
        foreach (self::TRIGGERS as $key => $def) {
            $out[$key] = $def + ['key' => $key];
        }

        return $out;
    }

    public static function get(string $key): ?array
    {
        $def = self::TRIGGERS[$key] ?? null;

        return $def ? $def + ['key' => $key] : null;
    }

    public static function has(string $key): bool
    {
        return isset(self::TRIGGERS[$key]);
    }

    /** Ayar ekranı için: grup anahtarı => ['label' => ..., 'triggers' => [...]] */
    public static function grouped(): array
    {
        $out = [];
        foreach (self::GROUPS as $groupKey => $groupLabel) {
            $out[$groupKey] = ['label' => $groupLabel, 'triggers' => []];
        }
        foreach (self::all() as $key => $def) {
            $out[$def['group']]['triggers'][$key] = $def;
        }

        return $out;
    }

    /** @return string[] */
    public static function scheduledKeys(): array
    {
        return array_keys(array_filter(self::TRIGGERS, fn ($d) => $d['kind'] === 'scheduled'));
    }

    /** @return string[] */
    public static function eventKeys(): array
    {
        return array_keys(array_filter(self::TRIGGERS, fn ($d) => $d['kind'] === 'event'));
    }
}
