<?php

namespace App\Services;

use App\Services\Sms\NetgsmSaglayici;
use App\Services\Sms\SmsGonderimInterface;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class SmsServisi
{
    /**
     * @var SmsGonderimInterface
     */
    protected $provider;

    public function __construct()
    {
        // Şimdilik sadece Netgsm var. Gelecekte burası dinamik hale getirilebilir.
        $this->provider = new NetgsmSaglayici();
    }

    /**
     * Bir kan ilanı için hedef kitleye SMS gönderir.
     *
     * @param int $kurumId
     * @param object $ilan
     * @return array
     */
    public function ilanSmsGonder(int $kurumId, object $ilan, string $ilanLink = null): array
    {
        // 1. Kurumun SMS ayarlarını al
        $smsAyarlari = DB::table('kurum_sms_ayarlari')->where('kurum_id', $kurumId)->first();

        if (!$smsAyarlari || !$smsAyarlari->aktif) {
            return ['status' => 'error', 'message' => 'Kurum için SMS gönderimi aktif değil veya ayarlar bulunamadı.'];
        }

        // 2. SMS şablonunu al
        $sablon = DB::table('sms_sablonlari')
            ->where('kurum_id', $kurumId)
            ->where('kod', 'ilan_bildirimi')
            ->where('aktif_mi', true)
            ->first();

        if (!$sablon) {
            return ['status' => 'error', 'message' => 'Aktif bir ilan bildirimi SMS şablonu bulunamadı.'];
        }

        // 3. Hedef kitleyi bul (SMS izni olan ve kan grubu uyan kullanıcılar)
        $hedefKullanicilar = DB::table('kullanicilar')
            ->where('kurum_id', $kurumId)
            ->where('sms_izni', true)
            ->where('kan_grubu_id', $ilan->kan_grubu_id) // Kan grubu ID ile eşleştir
            // TODO: Gelecekte kan grubu uyumluluk tablosuna göre daha gelişmiş eşleştirme eklenebilir (A+ → A+, AB+, O+, O- verebilir)
            ->pluck('telefon')
            ->toArray();

        if (empty($hedefKullanicilar)) {
            return ['status' => 'info', 'message' => 'Hedef kitlede uygun kan grubuna sahip ve SMS izni olan kimse bulunamadı.'];
        }

        // 4. Mesaj içeriğini oluştur
        $mesaj = $this->mesajiOlustur($sablon->icerik, $ilan, $ilanLink);

        // 5. SMS'i gönder
        $apiAyarlari = [
            'username' => $smsAyarlari->api_key,
            'password' => $smsAyarlari->api_secret,
        ];
        $baslik = $smsAyarlari->api_header;

        // ÖNEMLİ: Paylaşımlı hosting'de anlık gönderim yapıyoruz.
        // Yüksek hacimli gönderimler için numaraları parçalara ayırmak (chunking) gerekebilir.
        $toplamBasarili = 0;
        $toplamHata = 0;
        $hatalar = [];

        $numaraParcalari = array_chunk($hedefKullanicilar, 100); // Netgsm tek seferde 1000'e kadar destekler, 100 güvenli bir sayıdır.

        foreach ($numaraParcalari as $parca) {
            $sonuc = $this->provider->gonder($apiAyarlari, $baslik, $mesaj, $parca);

            // 6. Sonuçları logla
            $this->logla($kurumId, $ilan->id, $sonuc, $parca, $mesaj);

            if ($sonuc['status'] === 'success') {
                $toplamBasarili += count($parca);
            } else {
                $toplamHata += count($parca);
                $hatalar[] = $sonuc['message'];
            }
        }

        if ($toplamHata > 0) {
             return [
                'status' => 'warning',
                'message' => "SMS gönderimi tamamlandı ancak bazı hatalar oluştu. Başarılı: {$toplamBasarili}, Hatalı: {$toplamHata}.",
                'errors' => array_unique($hatalar)
            ];
        }

        return [
            'status' => 'success',
            'message' => "{$toplamBasarili} kişiye kan ilanı SMS'i başarıyla gönderildi."
        ];
    }

    /**
     * Şablon içeriğindeki placeholder'ları gerçek verilerle değiştirir.
     *
     * @param string $sablonIcerik
     * @param object $ilan
     * @param string|null $ilanLink
     * @return string
     */
    private function mesajiOlustur(string $sablonIcerik, object $ilan, string $ilanLink = null): string
    {
        $ilanSahibi = DB::table('kullanicilar')->find($ilan->kullanici_id);
        $kurum = DB::table('kurumlar')->find($ilan->kurum_id);
        $kanGrubu = DB::table('kan_gruplari')->find($ilan->kan_grubu_id);
        $il = DB::table('iller')->find($ilan->il_id);
        $ilce = DB::table('ilceler')->find($ilan->ilce_id);

        // Eğer link parametresi verilmişse onu kullan
        if ($ilanLink) {
            $ilanLinki = $ilanLink;
        } else {
            // Token yoksa veya süresi dolmuşsa yeni token oluştur (48 saat geçerli)
            $token = $ilan->link_token;
            if (!$token || ($ilan->link_gecerlilik_tarihi && now()->greaterThan($ilan->link_gecerlilik_tarihi))) {
                $token = update_ilan_link_token($ilan->id);
            }

            // Token ile kısa link oluştur
            if ($kurum && $kurum->ana_domain) {
                $ilanLinki = "http://" . $kurum->ana_domain . "/i/" . $token;
            } else {
                // Fallback: config'den app url kullan
                $ilanLinki = config('app.url') . "/i/" . $token;
            }
        }

        $placeholders = [
            '{hastane}' => $ilan->hastane_adi ?? 'Bilinmiyor',
            '{kan_grubu}' => $kanGrubu->ad ?? 'Bilinmiyor',
            '{unite}' => $ilan->unite_sayisi ?? '?',
            '{tarih}' => $ilan->tarih ? \Carbon\Carbon::parse($ilan->tarih)->format('d.m.Y') : '',
            '{saat}' => $ilan->saat ?? '',
            '{il}' => $il->ad ?? '',
            '{ilce}' => $ilce->ad ?? '',
            '{iletisim_telefon}' => $ilan->irtibat_telefonu ?? '',
            '{ilan_sahibi}' => $ilanSahibi ? $ilanSahibi->ad . ' ' . $ilanSahibi->soyad : 'Bilinmiyor',
            '{ilan_linki}' => $ilanLinki,
            
            // Eski placeholder'lar için uyumluluk
            '{hasta_ad_soyad}' => $ilan->hasta_ad_soyad ?? '',
            '{hastane_adi}' => $ilan->hastane_adi ?? '',
            '{unite_sayisi}' => $ilan->unite_sayisi ?? '',
        ];

        return str_replace(array_keys($placeholders), array_values($placeholders), $sablonIcerik);
    }

    /**
     * SMS gönderim sonucunu veritabanına kaydeder.
     *
     * @param int $kurumId
     * @param int $ilanId
     * @param array $sonuc
     * @param array $numaralar
     * @param string $mesaj
     */
    private function logla(int $kurumId, int $ilanId, array $sonuc, array $numaralar, string $mesaj): void
    {
        try {
            $logId = DB::table('sms_kayitlari')->insertGetId([
                'kurum_id' => $kurumId,
                'tip' => 'ilan_bildirimi',
                'telefon' => implode(',', $numaralar),
                'mesaj' => $mesaj,
                'hedef_numara_sayisi' => count($numaralar),
                'durum' => $sonuc['status'] === 'success' ? 'sent' : 'failed',
                'sms_saglayici_mesaj_id' => $sonuc['data']['message_id'] ?? null,
                'hata_mesaji' => $sonuc['status'] === 'error' ? $sonuc['message'] : null,
                'olusturulma_tarihi' => now(),
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            // Her numara için kan_ilan_smsleri tablosuna kayıt ekle
            if ($sonuc['status'] === 'success') {
                $kullaniciIds = DB::table('kullanicilar')
                    ->whereIn('telefon', $numaralar)
                    ->where('kurum_id', $kurumId)
                    ->pluck('id', 'telefon')
                    ->toArray();

                $ilanSmsData = [];
                foreach ($numaralar as $numara) {
                    $ilanSmsData[] = [
                        'kurum_id' => $kurumId,
                        'kan_ilan_id' => $ilanId,
                        'kullanici_id' => $kullaniciIds[$numara] ?? null,
                        'telefon' => $numara,
                        'sms_durumu' => 'sent',
                        'sms_saglayici_mesaj_id' => $sonuc['data']['message_id'] ?? null,
                        'gonderim_tarihi' => now(),
                        'created_at' => now(),
                        'updated_at' => now(),
                    ];
                }
                DB::table('kan_ilan_smsleri')->insert($ilanSmsData);
            }
        } catch (\Exception $e) {
            Log::error("SMS loglama hatası: " . $e->getMessage(), [
                'kurum_id' => $kurumId,
                'ilan_id' => $ilanId,
            ]);
        }
    }
}
