#!/usr/bin/env python3
"""
Vision Analyzer - PDF Sayfa Analiz Modülü
=========================================
PDF sayfasını görsel olarak analiz eder ve ustanın sorusuna cevap verir.

Akış:
1. PDF sayfası PNG'ye çevrilir
2. Ustanın sorusu sözlükten İngilizceye çevrilir
3. GPT-4o Vision'a gönderilir
4. Cevap sözlükten Türkçeye çevrilir
5. Ustaya sunulur

Güvenlik Kuralları:
- AI asla değer uydurmaz
- Görselde yoksa "göremiyorum" der
- Tehlikeli işlemlerde uyarı verir
- Kaynak sayfayı belirtir

Kullanım:
    from vision_analyzer import VisionAnalyzer
    
    analyzer = VisionAnalyzer()
    result = analyzer.analyze_page(
        pdf_path="/mnt/pdfs/JCB/330/330_SERVICE.pdf",
        page_number=412,
        question="bu şemadaki relief valf nerde"
    )
"""

import os
import json
import base64
import tempfile
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass

try:
    from openai import OpenAI
except ImportError:
    print("❌ openai yüklü değil: pip install openai")
    raise

try:
    import fitz  # PyMuPDF
except ImportError:
    print("❌ pymupdf yüklü değil: pip install pymupdf")
    fitz = None

from smart_translator import SmartTranslator


# ==================== CONFIGURATION ====================

# PDF mount path
PDF_MOUNT_PATH = os.getenv("PDF_MOUNT_PATH", "/mnt/pdfs")

# Vision model (gpt-4o-mini de vision destekliyor)
VISION_MODEL = os.getenv("VISION_MODEL", "gpt-4o-mini")
MAX_TOKENS = 2000  # Daha uzun cevaplar için artırıldı

# Güvenlik system prompt'u
SYSTEM_PROMPT = """Sen bir iş makinası uzmanısın. Usta sana bir servis manueli sayfası gösteriyor ve soru soruyor.

KRİTİK KURALLAR - İHLAL ETME:

1. **ASLA DEĞER UYDURMA**
   - Görselde yazılı olan değerleri ver
   - Değer göremiyorsan "Bu değeri görselde göremiyorum" de
   - Tahmini değer verme - YANLIŞ DEĞİŞ ÖLÜME YOL AÇABİLİR

2. **KAYNAK BELİRT**
   - Hangi şekil/tablo/bölümden aldığını söyle
   - Örnek: "Şekil 3-2'de gösterilen relief valve..."

3. **GÜVENLİK UYARILARI**
   - Tehlikeli işlemlerde (basınç, elektrik) uyar
   - "DİKKAT: Bu işlem önce makine kapatılmalı"
   - Koruyucu ekipman hatırlat

4. **BİRİMLERİ KORU**
   - Bar/psi, Nm/ft-lb farkına dikkat
   - Orijinal birimle birlikte ver

5. **NET VE KISA CEVAP**
   - Uzun paragraflar yazma
   - Adım adım açıkla
   - Madde işaretleri kullan

6. **TÜRKÇE CEVAP**
   - Teknik terimlerin Türkçe karşılığını parantez içinde ver
   - Örnek: "Relief valve (emniyet valfi)"

BİLMİYORSAN "BİLMİYORUM" DE - Bu da bir cevaptır ve yanlış cevaptan iyidir."""


@dataclass
class AnalysisResult:
    """Analiz sonucu"""
    pdf_path: str
    page_number: int
    original_question: str
    translated_question: str
    answer: str
    answer_turkish: str
    safety_warnings: List[str]
    referenced_items: List[str]  # Şekil 3-2, Tablo 4 gibi
    confidence: str  # "high", "medium", "low"
    error: Optional[str] = None
    
    def to_dict(self) -> Dict:
        return {
            "pdf_path": self.pdf_path,
            "page_number": self.page_number,
            "question": self.original_question,
            "answer": self.answer_turkish,
            "answer_english": self.answer,
            "safety_warnings": self.safety_warnings,
            "referenced_items": self.referenced_items,
            "confidence": self.confidence,
            "error": self.error
        }


class VisionAnalyzer:
    """
    PDF Sayfa Analiz Servisi
    
    PDF sayfasını görsel olarak analiz eder ve ustanın sorusuna cevap verir.
    """
    
    def __init__(
        self,
        openai_api_key: str = None,
        dictionary_path: str = None,
        pdf_mount_path: str = PDF_MOUNT_PATH
    ):
        # OpenAI client
        api_key = openai_api_key or os.getenv("OPENAI_API_KEY")
        if not api_key:
            raise ValueError("OPENAI_API_KEY gerekli!")
        self.openai = OpenAI(api_key=api_key)
        
        # Smart Translator (Sözlük Context için)
        self.translator = SmartTranslator(api_key=api_key)
        
        # PDF mount path
        self.pdf_mount_path = pdf_mount_path
        
        print(f"✓ Vision Analyzer hazır (Model: {VISION_MODEL})")
    
    def _render_page_to_image(self, pdf_path: str, page_number: int) -> Optional[str]:
        """
        PDF sayfasını PNG'ye render et ve base64 döndür.
        
        Args:
            pdf_path: PDF dosya yolu
            page_number: Sayfa numarası (1-based)
            
        Returns:
            Base64 encoded PNG string veya None
        """
        if fitz is None:
            print("❌ PyMuPDF yüklü değil!")
            return None
        
        try:
            # PDF'yi aç
            doc = fitz.open(pdf_path)
            
            # Sayfa numarası kontrolü (fitz 0-based)
            page_idx = page_number - 1
            if page_idx < 0 or page_idx >= len(doc):
                print(f"❌ Geçersiz sayfa numarası: {page_number} (Toplam: {len(doc)})")
                return None
            
            # Sayfayı al
            page = doc[page_idx]
            
            # Yüksek kalitede render (2x zoom)
            mat = fitz.Matrix(2.0, 2.0)
            pix = page.get_pixmap(matrix=mat)
            
            # PNG'ye çevir
            png_bytes = pix.tobytes("png")
            
            # Base64 encode
            base64_image = base64.b64encode(png_bytes).decode('utf-8')
            
            doc.close()
            return base64_image
            
        except Exception as e:
            print(f"❌ PDF render hatası: {e}")
            return None
    
    def _extract_safety_warnings(self, text: str) -> List[str]:
        """Metinden güvenlik uyarılarını çıkar"""
        warnings = []
        
        warning_keywords = [
            "dikkat", "uyarı", "tehlike", "güvenlik",
            "caution", "warning", "danger", "safety",
            "makineyi kapat", "basınç", "elektrik", "sıcak"
        ]
        
        lines = text.split('\n')
        for line in lines:
            line_lower = line.lower()
            if any(kw in line_lower for kw in warning_keywords):
                clean_line = line.strip()
                if clean_line and len(clean_line) > 10:
                    warnings.append(clean_line)
        
        return warnings[:5]  # Max 5 uyarı
    
    def _extract_references(self, text: str) -> List[str]:
        """Metinden referansları çıkar (Şekil 3-2, Tablo 4 gibi)"""
        import re
        
        references = []
        
        # Pattern'ler
        patterns = [
            r'[Şş]ekil\s*\d+[-.]?\d*',
            r'[Ff]igure\s*\d+[-.]?\d*',
            r'[Tt]ablo\s*\d+[-.]?\d*',
            r'[Tt]able\s*\d+[-.]?\d*',
            r'[Ss]tep\s*\d+',
            r'[Aa]dım\s*\d+',
            r'[Ii]tem\s*#?\d+',
        ]
        
        for pattern in patterns:
            matches = re.findall(pattern, text, re.IGNORECASE)
            references.extend(matches)
        
        return list(set(references))[:10]  # Max 10 referans
    
    def _determine_confidence(self, answer: str) -> str:
        """Cevabın güven seviyesini belirle"""
        low_confidence_phrases = [
            "göremiyorum", "emin değilim", "net değil",
            "cannot see", "not sure", "unclear",
            "muhtemelen", "belki", "sanırım"
        ]
        
        medium_confidence_phrases = [
            "görünüyor", "olabilir", "gibi görünüyor",
            "appears to", "seems like", "likely"
        ]
        
        answer_lower = answer.lower()
        
        if any(phrase in answer_lower for phrase in low_confidence_phrases):
            return "low"
        elif any(phrase in answer_lower for phrase in medium_confidence_phrases):
            return "medium"
        else:
            return "high"
    
    def analyze_page(
        self,
        pdf_path: str,
        page_number: int,
        question: str,
        context: str = None
    ) -> AnalysisResult:
        """
        PDF sayfasını analiz et ve soruya cevap ver.
        
        Args:
            pdf_path: PDF dosya yolu (tam yol veya göreceli)
            page_number: Sayfa numarası
            question: Ustanın sorusu (Türkçe)
            context: Ek bağlam bilgisi (opsiyonel)
            
        Returns:
            AnalysisResult nesnesi
        """
        # PDF yolunu çöz
        # Qdrant'tan gelen yol: /home/poyraz/pdfs/... -> /mnt/pdfs/...
        if pdf_path.startswith("/home/poyraz/pdfs/"):
            pdf_path = pdf_path.replace("/home/poyraz/pdfs/", self.pdf_mount_path + "/")
        elif not os.path.isabs(pdf_path):
            # pdfs/ prefix'i varsa kaldır
            if pdf_path.startswith("pdfs/"):
                pdf_path = pdf_path[5:]
            pdf_path = os.path.join(self.pdf_mount_path, pdf_path)
        
        # Dosya kontrolü
        if not os.path.exists(pdf_path):
            return AnalysisResult(
                pdf_path=pdf_path,
                page_number=page_number,
                original_question=question,
                translated_question="",
                answer="",
                answer_turkish="",
                safety_warnings=[],
                referenced_items=[],
                confidence="low",
                error=f"PDF bulunamadı: {pdf_path}"
            )
        
        # 1. Sorudaki teknik terimleri bul (Context için)
        relevant_terms = self.translator.get_relevant_terms(question)
        translated_question = "" # Artık çeviri yapmıyoruz, orijinal soruyu ve terimleri yolluyoruz
        
        # İngilizce terimler varsa raporla
        english_terms = list(relevant_terms.values())
        
        # 2. PDF sayfasını render et
        base64_image = self._render_page_to_image(pdf_path, page_number)
        
        if not base64_image:
            return AnalysisResult(
                pdf_path=pdf_path,
                page_number=page_number,
                original_question=question,
                translated_question=translated_question,
                answer="",
                answer_turkish="",
                safety_warnings=[],
                referenced_items=[],
                confidence="low",
                error=f"Sayfa render edilemedi: {page_number}"
            )
        
        # 3. GPT-4o Vision'a gönder
        try:
            # Prompt oluştur
            user_content = f"""Sayfa bilgisi: {os.path.basename(pdf_path)}, Sayfa {page_number}

Ustanın sorusu: {question}

Ustanın sorusu: {question}
336: 
337: (Bulunan Teknik Terimler: {json.dumps(relevant_terms, ensure_ascii=False)})"""
            
            if context:
                user_content += f"\n\nEk bilgi: {context}"
            
            response = self.openai.chat.completions.create(
                model=VISION_MODEL,
                messages=[
                    {
                        "role": "system",
                        "content": SYSTEM_PROMPT
                    },
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": user_content
                            },
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/png;base64,{base64_image}",
                                    "detail": "high"
                                }
                            }
                        ]
                    }
                ],
                max_tokens=MAX_TOKENS
            )
            
            answer = response.choices[0].message.content
            
        except Exception as e:
            return AnalysisResult(
                pdf_path=pdf_path,
                page_number=page_number,
                original_question=question,
                translated_question=translated_question,
                answer="",
                answer_turkish="",
                safety_warnings=[],
                referenced_items=[],
                confidence="low",
                error=f"Vision API hatası: {str(e)}"
            )
        
        # 4. Cevabı işle
        # Cevap zaten Türkçe olmalı (system prompt'ta istedik)
        answer_turkish = answer
        
        # Güvenlik uyarılarını çıkar
        safety_warnings = self._extract_safety_warnings(answer)
        
        # Referansları çıkar
        referenced_items = self._extract_references(answer)
        
        # Güven seviyesini belirle
        confidence = self._determine_confidence(answer)
        
        return AnalysisResult(
            pdf_path=pdf_path,
            page_number=page_number,
            original_question=question,
            translated_question=translated_question,
            answer=answer,
            answer_turkish=answer_turkish,
            safety_warnings=safety_warnings,
            referenced_items=referenced_items,
            confidence=confidence
        )
    
    def analyze_with_context(
        self,
        pdf_path: str,
        page_number: int,
        question: str,
        context_pages: int = 1
    ) -> AnalysisResult:
        """
        PDF sayfasını çevresindeki sayfalarla birlikte analiz et.
        
        Bazı şemalar birden fazla sayfaya yayılabilir.
        """
        # Bu versiyon sadece tek sayfa analiz ediyor
        # İlerleyen versiyonlarda çoklu sayfa desteği eklenebilir
        return self.analyze_page(pdf_path, page_number, question)
    
    def close(self):
        """Kaynakları temizle"""
        pass


# ==================== CLI INTERFACE ====================

def main():
    """CLI arayüzü"""
    import argparse
    
    parser = argparse.ArgumentParser(description="Vision Analyzer")
    parser.add_argument("pdf", nargs="?", help="PDF dosya yolu")
    parser.add_argument("-p", "--page", type=int, default=1, help="Sayfa numarası")
    parser.add_argument("-q", "--question", help="Soru")
    
    args = parser.parse_args()
    
    # API Key kontrolü
    if not os.getenv("OPENAI_API_KEY"):
        print("❌ OPENAI_API_KEY ortam değişkeni ayarlanmalı!")
        print("   export OPENAI_API_KEY='sk-...'")
        return
    
    if fitz is None:
        print("❌ PyMuPDF yüklü değil!")
        print("   pip install pymupdf")
        return
    
    if not args.pdf:
        # İnteraktif mod
        print("\n" + "=" * 70)
        print("   🔍 VISION ANALYZER")
        print("   PDF sayfasını analiz eder ve sorularınıza cevap verir")
        print("=" * 70)
        
        analyzer = VisionAnalyzer()
        
        while True:
            try:
                pdf_path = input("\n📁 PDF yolu (q=çıkış): ").strip()
                if pdf_path.lower() == 'q':
                    break
                if not pdf_path:
                    continue
                
                page_str = input("📄 Sayfa numarası: ").strip()
                page_number = int(page_str) if page_str else 1
                
                question = input("❓ Sorunuz: ").strip()
                if not question:
                    question = "Bu sayfada ne var?"
                
                print("\n🔄 Analiz ediliyor...")
                result = analyzer.analyze_page(pdf_path, page_number, question)
                
                if result.error:
                    print(f"❌ Hata: {result.error}")
                else:
                    print(f"\n{'=' * 60}")
                    print(f"📋 CEVAP (Güven: {result.confidence})")
                    print(f"{'=' * 60}")
                    print(result.answer_turkish)
                    
                    if result.safety_warnings:
                        print(f"\n⚠️ GÜVENLİK UYARILARI:")
                        for w in result.safety_warnings:
                            print(f"   • {w}")
                    
                    if result.referenced_items:
                        print(f"\n📎 REFERANSLAR: {', '.join(result.referenced_items)}")
                
            except KeyboardInterrupt:
                break
            except ValueError:
                print("❌ Geçersiz sayfa numarası")
            except Exception as e:
                print(f"❌ Hata: {e}")
        
        analyzer.close()
        print("\n👋 Güle güle!")
    else:
        # Tek dosya modu
        if not args.question:
            print("❌ Soru gerekli: --question 'sorunuz'")
            return
        
        analyzer = VisionAnalyzer()
        result = analyzer.analyze_page(args.pdf, args.page, args.question)
        
        if result.error:
            print(f"❌ Hata: {result.error}")
        else:
            import json
            print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2))
        
        analyzer.close()


if __name__ == "__main__":
    main()

