<?php

namespace App\Services;

use App\Models\BlogPost;
use App\Models\LibraryContent;
use App\Models\LibraryCategory;
use App\Models\ForumTopic;
use App\Models\ForumCategory;
use App\Models\ChatMessage;
use App\Models\ChatRoom;
use Illuminate\Support\Str;

class ChatBotService
{
    /**
     * Soru kelimeleri - bot tetikleme için
     */
    protected array $questionWords = [
        'nedir', 'nasıl', 'nasil', 'neden', 'kim', 'nerede', 'ne zaman', 'kaç', 'kac', 'hangi',
        'mi', 'mu', 'mü', 'mu', 'mı', 'mi', // Soru ekleri (both Turkish variants)
        'kadar', 'hakkında', 'hakkinda', 'gibi', 'dair',
        'olur', 'olunur', 'olmak', 'yapilir', 'yapılır', 'alım', 'alim', 'basvuru', 'başvuru',
    ];

    /**
     * Askeri konu anahtar kelimeleri
     */
    protected array $militaryKeywords = [
        // Kurumlar ve okullar
        'msü', 'msb', 'tsk', 'askeri', 'harbiye', 'kara harp okulu', 'hava harp okulu',
        'deniz harp okulu', 'jandarma', 'sahil güvenlik', 'polis akademisi', 'emniyet',
        // Rütbe ve pozisyonlar
        'subay', 'astsubay', 'uzman erbaş', 'uzman çavuş', 'teğmen', 'üsteğmen',
        'yüzbaşı', 'binbaşı', 'yarbay', 'albay', 'general', 'amiral', 'tuğgeneral',
        // Sınav ve başvuru
        'başvuru', 'şartları', 'sınav', 'puan', 'taban', 'tavan', 'kontenjan',
        'mülakat', 'fizik', 'psikolojik', 'fiziksel', 'alım', 'atama', 'kadro',
        // Askerlik
        'askerlik', 'bedelli', 'bakaya', 'yedek', 'terhis', 'ertelemek', 'erteleme',
        'celp', 'nasbı', 'nasıp',
        // Özelleşmiş aramalar
        'uzman erbaş alım', 'uzman erbaş alımı', 'uzman erbaş ne zaman',
        'subay nasıl olunur', 'subay olmak', 'subay başvuru',
        'astsubay alım', 'astsubay nasıl', 'astsubay olmak',
        'msb uzman', 'msb alım', 'kara kuvvetleri alım', 'jandarma alım',
    ];

    /**
     * Mesajın bot tarafından yanıtlanıp yanıtlanmayacağını kontrol et
     *
     * Bot yanıt verecek koşullar:
     * 1. Soru işareti (?) ile bitiyor VE askeri/ilgili keyword içeriyor
     * 2. VEYA Soru kelimesi içeriyor VE askeri/ilgili keyword içeriyor
     * 3. VEYA Doğrudan askeri bir keyword içeriyor (gerçekten spesifik olanlar)
     */
    public function shouldRespond(string $message): bool
    {
        $messageLower = mb_strtolower(trim($message), 'UTF-8');

        // Boş mesaj
        if (empty($messageLower)) {
            return false;
        }

        // Çok kısa mesajlar - kontrol et
        $wordCount = count(explode(' ', $messageLower));
        if ($wordCount < 2) {
            return false; // Tek kelime mesajlara yanıt verme
        }

        // Askeri keyword içerip içermediğini kontrol et
        $hasMilitaryKeyword = false;
        foreach ($this->militaryKeywords as $keyword) {
            if (Str::contains($messageLower, $keyword)) {
                $hasMilitaryKeyword = true;
                break;
            }
        }

        // Soru işareti varsa VE askeri keyword varsa yanıt ver
        if (Str::endsWith($messageLower, '?') && $hasMilitaryKeyword) {
            return true;
        }

        // Soru kelimesi varsa VE askeri keyword varsa yanıt ver
        $hasQuestionWord = false;
        foreach ($this->questionWords as $word) {
            if (Str::contains($messageLower, $word)) {
                $hasQuestionWord = true;
                break;
            }
        }

        if ($hasQuestionWord && $hasMilitaryKeyword) {
            return true;
        }

        // Çok spesifik askeri konular doğrudan keyword eşleşmesi
        // (Ör: "MSÜ ne zaman", "Subay başvuru" gibi)
        $verySpecificKeywords = [
            'msu', 'msü', 'subay', 'astsubay', 'uzman erbaş', 'uzman erbas',
            'msb', 'jandarma', 'askeri', 'harp okulu', 'bedelli askerlik'
        ];
        
        $hasVerySpecificKeyword = false;
        foreach ($verySpecificKeywords as $keyword) {
            if (Str::contains($messageLower, $keyword)) {
                $hasVerySpecificKeyword = true;
                break;
            }
        }

        // Çok spesifik keyword + (soru işareti VEYA soru kelimesi)
        if ($hasVerySpecificKeyword && (Str::endsWith($messageLower, '?') || $hasQuestionWord)) {
            return true;
        }

        return false;
    }

    /**
     * İçerik ara (Blog, Library, Forum)
     * 
     * @param string $query Arama sorgusu
     * @param int $limit Sonuç limiti
     * @return array ['blog' => [], 'library' => [], 'forum' => []]
     */
    public function searchContent(string $query, int $limit = 3): array
    {
        $results = [
            'blog' => [],
            'library' => [],
            'forum' => [],
        ];

        // Blog araması - published scope yerine daha geniş arama
        $blogResults = BlogPost::where('status', 'published')
            ->where(function ($q) use ($query) {
                $terms = $this->extractKeywords($query);
                foreach ($terms as $term) {
                    $q->orWhere('title', 'like', "%{$term}%")
                      ->orWhere('excerpt', 'like', "%{$term}%")
                      ->orWhere('content', 'like', "%{$term}%");
                }
            })
            ->limit($limit)
            ->get(['id', 'title', 'slug', 'excerpt']);

        foreach ($blogResults as $post) {
            $results['blog'][] = [
                'type' => 'blog',
                'title' => $post->title,
                'url' => route('blog.show', $post),
                'excerpt' => Str::limit(strip_tags($post->excerpt ?? $post->content), 100),
            ];
        }

        // Kütüphane araması
        $libraryResults = LibraryContent::active()
            ->with('category')
            ->where(function ($q) use ($query) {
                $q->where('title', 'like', "%{$query}%")
                  ->orWhere('content', 'like', "%{$query}%");
            })
            ->limit($limit)
            ->get(['id', 'title', 'slug', 'type', 'category_id']);

        foreach ($libraryResults as $content) {
            $results['library'][] = [
                'type' => 'library',
                'title' => $content->title,
                'url' => $content->category ? route('library.show', [$content->category, $content]) : '#',
                'content_type' => $content->type,
            ];
        }

        // Forum araması
        $forumResults = ForumTopic::active()
            ->with('category')
            ->where(function ($q) use ($query) {
                $q->where('title', 'like', "%{$query}%")
                  ->orWhere('content', 'like', "%{$query}%");
            })
            ->limit($limit)
            ->get(['id', 'title', 'slug', 'category_id', 'reply_count']);

        foreach ($forumResults as $topic) {
            $results['forum'][] = [
                'type' => 'forum',
                'title' => $topic->title,
                'url' => $topic->category ? route('forum.topic', [$topic->category, $topic]) : '#',
                'reply_count' => $topic->reply_count,
            ];
        }

        return $results;
    }

    /**
     * Yapay zeka benzeri yanıt oluştur (HTML formatında)
     *
     * @param string $query Kullanıcı sorusu
     * @param array $sources Bulunan kaynaklar
     * @return string Formatlanmış HTML yanıt
     */
    public function generateResponse(string $query, array $sources): string
    {
        $allSources = array_merge($sources['blog'], $sources['library'], $sources['forum']);

        // İçeriğe göre kısa açıklama - kaynak olsa da olmasa da yanıt ver
        $contextText = $this->generateContextualResponse($query, $allSources);

        $html = '<div class="bot-response-text">' . htmlspecialchars($contextText) . '</div>';

        // Kaynak varsa linkleri ekle
        if (!empty($allSources)) {
            $html .= '<div class="bot-sources" style="margin-top:10px;">';
            $html .= '<strong style="font-size:12px;opacity:0.9;">📚 Kaynaklar:</strong>';

            if (!empty($sources['blog'])) {
                $html .= '<div style="margin-top:6px;font-size:12px;opacity:0.85;">📝 Blog:</div>';
                foreach ($sources['blog'] as $source) {
                    $title = htmlspecialchars($source['title']);
                    $url = htmlspecialchars($source['url']);
                    $html .= '<div style="margin-top:4px;">→ <a href="' . $url . '" target="_blank" style="color:white;text-decoration:underline;font-size:12px;">' . $title . '</a></div>';
                }
            }

            if (!empty($sources['library'])) {
                $html .= '<div style="margin-top:6px;font-size:12px;opacity:0.85;">📚 Kütüphane:</div>';
                foreach ($sources['library'] as $source) {
                    $title = htmlspecialchars($source['title']);
                    $url = htmlspecialchars($source['url']);
                    $html .= '<div style="margin-top:4px;">→ <a href="' . $url . '" target="_blank" style="color:white;text-decoration:underline;font-size:12px;">' . $title . '</a></div>';
                }
            }

            if (!empty($sources['forum'])) {
                $html .= '<div style="margin-top:6px;font-size:12px;opacity:0.85;">💬 Forum:</div>';
                foreach ($sources['forum'] as $source) {
                    $title = htmlspecialchars($source['title']);
                    $url = htmlspecialchars($source['url']);
                    $html .= '<div style="margin-top:4px;">→ <a href="' . $url . '" target="_blank" style="color:white;text-decoration:underline;font-size:12px;">' . $title . '</a></div>';
                }
            }

            $html .= '</div>';
        }

        return $html;
    }

    /**
     * Arama sorgusundan anahtar kelimeleri çıkar
     */
    protected function extractKeywords(string $query): array
    {
        $query = mb_strtolower(trim($query), 'UTF-8');
        $query = preg_replace('/[^\p{L}\p{M}\s]+/u', ' ', $query); // Sadece harf ve boşluk bırak
        $words = explode(' ', $query);
        
        // Kısa kelimeleri ve yaygın kelimeleri filtrele
        $stopWords = ['ve', 'veya', 'ile', 'için', 'hakkında', 'hakkinda', 'gibi', 'dair', 'olan', 'olan', 'bu', 'şu', 'bir', 've'];
        
        return array_filter($words, function($word) use ($stopWords) {
            return mb_strlen($word, 'UTF-8') > 2 && !in_array($word, $stopWords);
        });
    }

    /**
     * İçeriğe göre kısa açıklama oluştur
     */
    protected function generateContextualResponse(string $query, array $sources): string
    {
        $queryLower = mb_strtolower($query, 'UTF-8');

        // MSÜ/Askeri konuları için özel yanıtlar (kaynak olsa da olmasa da)
        foreach ($this->militaryKeywords as $keyword) {
            if (Str::contains($queryLower, $keyword)) {
                return $this->getMilitaryResponse($query, $sources);
            }
        }

        // Genel yanıt - kaynak varsa say, yoksa genel mesaj
        $count = count($sources);
        if ($count === 0) {
            return "Bu konuyla ilgili henüz içerik bulunamadı. Farklı bir arama terimi deneyebilir veya forumda soru sorabilirsiniz.";
        } elseif ($count === 1) {
            return "Bu konuyla ilgili 1 kaynak buldum. Detaylı bilgi için kaynaklara göz atabilirsiniz.";
        } elseif ($count <= 3) {
            return "Bu konuyla ilgili {$count} kaynak buldum. Detaylı bilgi için aşağıdaki kaynaklara göz atabilirsiniz.";
        } else {
            return "Bu konuyla ilgili {$count} kaynak buldum. Detaylı bilgi için aşağıdaki kaynaklara göz atabilirsiniz.";
        }
    }

    /**
     * Askeri konular için özel yanıt
     */
    protected function getMilitaryResponse(string $query, array $sources): string
    {
        $q = mb_strtolower($query, 'UTF-8');
        $hasSource = !empty($sources);
        $suffix = $hasSource
            ? " Detaylı bilgiler için aşağıdaki kaynaklara göz atabilirsiniz."
            : " Yakında bu konuda içerik eklenecektir. Forumda soru sorabilirsiniz.";

        // Subay ile ilgili sorular (Turkish + ASCII variants)
        if (Str::contains($q, 'subay') && (
            Str::contains($q, 'nasıl') || Str::contains($q, 'nasil') ||
            Str::contains($q, 'olunur') || Str::contains($q, 'olmak') ||
            Str::contains($q, 'olmak') || Str::contains($q, 'olma')
        )) {
            return "Subay olmak için MSÜ (Milli Savunma Üniversitesi) bünyesindeki Kara, Hava veya Deniz Harp Okulu'na başvurabilirsiniz. MSÜ 4 yıllık lisans eğitimi verir ve mezunlar teğmen rütbesiyle göreve başlar. Başvuru için YKS/TYT puanı, fizik testi ve mülakat aşamaları gereklidir." . $suffix;
        }

        // Astsubay alımı ile ilgili
        if (Str::contains($q, 'astsubay') && (
            Str::contains($q, 'alım') || Str::contains($q, 'alim') ||
            Str::contains($q, 'ne zaman') || Str::contains($q, 'nasıl') || Str::contains($q, 'nasil') ||
            Str::contains($q, 'olmak') || Str::contains($q, 'basvuru') || Str::contains($q, 'başvuru')
        )) {
            return "Astsubay olmak için MSÜ Astsubay Meslek Yüksekokulu'na başvurabilirsiniz. Yazılı sınav (YKS/TYT), fizik yeterlilik testi ve mülakat aşamaları vardır. 2 yıllık eğitim sonrası astsubay çavuş rütbesiyle göreve başlanır." . $suffix;
        }

        // Uzman Erbaş alımı (Turkish + ASCII)
        if ((Str::contains($q, 'uzman erbaş') || Str::contains($q, 'uzman erbas')) && (
            Str::contains($q, 'alım') || Str::contains($q, 'alim') ||
            Str::contains($q, 'ne zaman') || Str::contains($q, 'nasıl') || Str::contains($q, 'nasil')
        )) {
            return "Uzman Erbaş alımı MSB (Milli Savunma Bakanlığı) tarafından yıllık dönemlerde ilan edilmektedir. En az lise mezunu olmak, 18-30 yaş arasında olmak ve sağlık şartlarını karşılamak gerekmektedir. Yazılı sınav ve fiziksel yeterlilik testi uygulanmaktadır." . $suffix;
        }

        // MSB Uzman Erbaş özel sorgusu
        if (Str::contains($q, 'msb') && (Str::contains($q, 'uzman') || Str::contains($q, 'alım') || Str::contains($q, 'alim'))) {
            return "MSB Uzman Erbaş alımı, Milli Savunma Bakanlığı tarafından belirlenen kontenjan ve takvime göre gerçekleştirilmektedir. Başvurular e-devlet üzerinden yapılmakta olup alım dönemleri yılda birkaç kez açıklanmaktadır." . $suffix;
        }

        // Sözleşmeli Er/Erbaş
        if (Str::contains($q, 'sözleşmeli') || Str::contains($q, 'sozlesmeli')) {
            return "Sözleşmeli Erbaş/Er alımı, Türk Silahlı Kuvvetleri'nde çeşitli branşlarda gerçekleştirilmektedir. En az ilköğretim mezunu olmak, 18-27 yaş arasında bulunmak ve fiziksel yeterlilik şartlarını karşılamak gerekir. Sözleşme süresi uzatılabilmektedir." . $suffix;
        }

        // Başvuru şartları
        if (Str::contains($q, 'başvuru') || Str::contains($q, 'basvuru') || Str::contains($q, 'şart') || Str::contains($q, 'sart')) {
            return "Askeri okul ve alım başvuru şartları kuruma göre değişmektedir. Genel şartlar: Türk vatandaşı olmak, 18-27 yaş arasında olmak (kuruma göre değişir), lise veya üzeri mezuniyet, askerliğe engel sağlık durumu bulunmamak ve sabıka kaydı olmamaktır." . $suffix;
        }

        // Sınav ve puan
        if (Str::contains($q, 'sınav') || Str::contains($q, 'sinav') || Str::contains($q, 'puan') || Str::contains($q, 'taban')) {
            return "Askeri okul giriş sınavlarında YKS/TYT veya kuruma özel yazılı sınav uygulanmaktadır. Her okulun kendi taban puan şartı ve kontenjanı vardır. Fiziksel yeterlilik testi ve mülakat aşamaları da değerlendirmeye katılmaktadır." . $suffix;
        }

        // Mülakat
        if (Str::contains($q, 'mülakat') || Str::contains($q, 'mulakat')) {
            return "Askeri alım mülakatında fiziksel yeterlilik testi (koşu, şınav, mekik vb.), psikolojik değerlendirme ve mülakat komisyonu görüşmesi yapılmaktadır. Hazırlık için düzenli spor yapmanız ve güncel askeri gelişmeleri takip etmeniz tavsiye edilir." . $suffix;
        }

        // MSÜ/Harp okulu
        if (Str::contains($q, 'msü') || Str::contains($q, 'msu') || Str::contains($q, 'harp okulu') || Str::contains($q, 'harbiye')) {
            return "MSÜ (Milli Savunma Üniversitesi) bünyesinde Kara Harp Okulu, Hava Harp Okulu ve Deniz Harp Okulu bulunmaktadır. YKS/TYT sınavı, fiziksel yeterlilik testi ve mülakat aşamalarından geçilmektedir. Mezunlar teğmen rütbesiyle göreve başlar." . $suffix;
        }

        // Askerlik ve bedelli
        if (Str::contains($q, 'askerlik') || Str::contains($q, 'bedelli')) {
            return "Türkiye'de yükümlü askerlik hizmeti bulunmaktadır. Bedelli askerlik seçeneği belirli dönemlerde açılmaktadır. Yüksekokul mezunları yedek subay veya yedek astsubay olarak görev yapabilmektedir." . $suffix;
        }

        // Terhis/Erteleme
        if (Str::contains($q, 'terhis') || Str::contains($q, 'ertele')) {
            return "Askerlik ertelemesi öğrencilere ve belirli meslek gruplarına tanınmaktadır. Terhis süreci hizmet bitiminde gerçekleşir. Detaylı bilgi için E-Devlet üzerinden askerlik işlemlerinizi takip edebilirsiniz." . $suffix;
        }

        // Alım genel
        if (Str::contains($q, 'alım') || Str::contains($q, 'alim') || Str::contains($q, 'ne zaman')) {
            return "Askeri personel alımları TSK, Jandarma ve Sahil Güvenlik bünyesinde çeşitli dönemlerde yapılmaktadır. Güncel alım ilanları MSB'nin resmi sitesinde ve e-devlet portalında yayımlanmaktadır." . $suffix;
        }

        return "Askeri eğitim ve kariyer hakkında genel bilgi: TSK bünyesinde Subay, Astsubay, Uzman Erbaş ve Sözleşmeli Er kadroları mevcuttur. Her kadronun farklı başvuru şartları ve süreçleri vardır." . $suffix;
    }

    /**
     * Bot yanıtını kaydet ve döndür
     * 
     * @param ChatRoom $room Sohbet odası
     * @param string $userMessage Kullanıcı mesajı
     * @return ChatMessage|null Bot mesajı veya null (sonuç yoksa)
     */
    public function createBotResponse(ChatRoom $room, string $userMessage): ?ChatMessage
    {
        // İçerik ara
        $sources = $this->searchContent($userMessage);

        // Yanıt oluştur
        $response = $this->generateResponse($userMessage, $sources);

        // Sonuç yoksa sessiz kal
        if (empty($response)) {
            return null;
        }

        // Bot mesajını kaydet
        $botMessage = ChatMessage::create([
            'room_id' => $room->id,
            'user_id' => null, // Bot mesajı, user_id null
            'message' => $response,
            'user_name' => '🤖 Asistan',
            'is_bot_message' => true,
            'bot_query' => $userMessage,
            'bot_sources' => $sources,
        ]);

        return $botMessage;
    }

    /**
     * Bot mesajı formatını JSON için hazırla
     */
    public function formatBotMessageForJson(ChatMessage $botMessage): array
    {
        return [
            'id' => $botMessage->id,
            'user_id' => null,
            'user_name' => '🤖 Asistan',
            'message' => $botMessage->message,
            'created_at' => $botMessage->created_at->format('H:i'),
            'avatar' => null,
            'is_bot' => true,
            'is_flagged' => false,
        ];
    }
}
