#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Bilingual Term Extractor for Hidromek Catalogs
İki dilli (TR/EN) kataloglardan terim çiftlerini çıkarır
"""

import fitz
import re
import json
from pathlib import Path
from collections import defaultdict
from typing import List, Dict, Tuple, Optional

class BilingualTermExtractor:
    """Hidromek kataloglarından TR/EN terim çiftleri çıkarır"""
    
    # İngilizce pattern'ler - bu kelimeler İngilizce satırı tanımlar
    EN_PATTERNS = [
        r'\b(ENGINE|SYSTEM|MOUNTING|ASSEMBLY|CYLINDER|VALVE|PUMP|FILTER|BRACKET|WASHER|BOLT|NUT|SEAL|GASKET|BEARING|SHAFT|GEAR|PLATE|COVER|HOUSING|HOSE|PIPE|CABLE|SWITCH|SENSOR|TANK|RADIATOR|EXHAUST|INTAKE|FUEL|OIL|AIR|WATER|HYDRAULIC|STEERING|BRAKE|TRANSMISSION|AXLE|WHEEL|TIRE|BUCKET|LOADER|BACKHOE|BLADE|ARM|BOOM|LINK|PIN|BUSH|RING|SPRING|CLAMP|CLIP|SCREW|STUD|CAP|PLUG|CONNECTOR|HARNESS|RELAY|FUSE|LAMP|MIRROR|GLASS|SEAT|CABIN|DOOR|WINDOW|PEDAL|LEVER|JOYSTICK|PANEL|GAUGE|INDICATOR|WARNING|CONTROL|ELECTRONIC|ELECTRICAL|MECHANICAL|COMPLETE|KIT|SET|LEFT|RIGHT|FRONT|REAR|UPPER|LOWER|INNER|OUTER|MAIN|SUB|WITH|WITHOUT|AND|FOR|NO|OP)\b',
    ]
    
    # Türkçe pattern'ler
    TR_PATTERNS = [
        r'[ÇĞİÖŞÜçğıöşü]',  # Türkçe karakterler
        r'\b(SİSTEMİ|MONTAJI|GRUBU|KOMPLESİ|SİLİNDİRİ|VALFİ|POMPASI|FİLTRESİ|BRAKETİ|PULU|CIVATA|SOMUN|CONTA|RULMAN|MİLİ|DİŞLİSİ|PLAKASI|KAPAĞI|GÖVDESİ|HORTUMU|BORUSU|KABLOSU|ŞALTERİ|SENSÖRÜ|DEPOSU|RADYATÖRÜ|EGSOZ|EMİŞ|YAKIT|YAĞ|HAVA|SU|HİDROLİK|DİREKSİYON|FREN|ŞANZIMAN|AKS|TEKERLEĞİ|LASTİK|KEPÇESİ|YÜKLEYİCİ|KAZICI|BIÇAK|KOL|BOM|BAĞLANTI|PİM|BURÇ|BİLEZİK|YAY|KELEPÇE|VİDA|TAPA|KONNEKTÖR|RÖLE|SİGORTA|LAMBA|AYNA|CAM|KOLTUK|KABİN|KAPI|PENCERE|PEDAL|KOLU|KUMANDA|PANEL|GÖSTERGE|UYARI|KONTROL|ELEKTRONİK|ELEKTRİK|MEKANİK|KOMPLE|TAKIMI|SOL|SAĞ|ÖN|ARKA|ÜST|ALT|İÇ|DIŞ|ANA|YARDIMCI)\b',
    ]
    
    def __init__(self, pdf_path: str):
        self.pdf_path = pdf_path
        self.doc = fitz.open(pdf_path)
        self.terms: Dict[str, str] = {}  # {tr_term: en_term}
        self.term_sources: Dict[str, List[int]] = defaultdict(list)  # {term: [page_nums]}
        
    def is_english_line(self, line: str) -> bool:
        """Satırın İngilizce olup olmadığını kontrol et"""
        # Türkçe karakter varsa İngilizce değil
        if re.search(r'[ÇĞİÖŞÜçğıöşü]', line):
            return False
        
        # İngilizce kelime pattern'i ara
        for pattern in self.EN_PATTERNS:
            if re.search(pattern, line, re.IGNORECASE):
                return True
        
        return False
    
    def is_turkish_line(self, line: str) -> bool:
        """Satırın Türkçe olup olmadığını kontrol et"""
        # Türkçe karakter içeriyorsa kesin Türkçe
        if re.search(r'[ÇĞİÖŞÜçğıöşü]', line):
            return True
        
        # Türkçe kelime pattern'i ara
        for pattern in self.TR_PATTERNS:
            if re.search(pattern, line, re.IGNORECASE):
                return True
        
        return False
    
    def clean_term(self, term: str) -> str:
        """Terimi temizle"""
        # Başındaki/sonundaki boşlukları kaldır
        term = term.strip()
        
        # Çoklu boşlukları tek boşluğa çevir
        term = re.sub(r'\s+', ' ', term)
        
        # Parça numaralarını kaldır (örn: A010.01.01)
        term = re.sub(r'^[A-Z]\d{3}\.\d{2}\.\d{2}\s*', '', term)
        
        # Seri numaralarını kaldır (örn: A70001 -)
        term = re.sub(r'^[A-Z]\d{5}\s*-?\s*', '', term)
        
        # Başındaki numaraları kaldır
        term = re.sub(r'^\d+\s+', '', term)
        
        # (OP), (1), (2) gibi suffixleri kaldır
        term = re.sub(r'\s*\([^)]*\)\s*$', '', term)
        
        return term.strip()
    
    # Reddetilecek pattern'ler
    REJECT_PATTERNS = [
        r'^SAYFA\s*(NO|ADI)',
        r'^PAGE\s*(NO|NAME)',
        r'^\d+$',  # Sadece sayı
        r'^[A-Z]\d{3}\.\d{2}\.\d{2}$',  # Parça kodu
        r'^EDITION\s+DATE',
        r'^BASKI\s+TARİHİ',
        r'^REVİZYON|^REVISION',
        r'^S\.K\.|^Y\.K\.|^S/N|^QTY',
        r'^NOT$|^NOTE$',
        r'^ADET$|^QTY$',
    ]
    
    def should_reject_term(self, term: str) -> bool:
        """Terimin reddedilip reddedilmeyeceğini kontrol et"""
        for pattern in self.REJECT_PATTERNS:
            if re.search(pattern, term, re.IGNORECASE):
                return True
        return False
    
    def are_similar_terms(self, tr: str, en: str) -> bool:
        """İki terimin eşleşip eşleşmediğini kontrol et"""
        # Reddedilmesi gereken terimleri filtrele
        if self.should_reject_term(tr) or self.should_reject_term(en):
            return False
        
        # Çok kısa terimleri reddet
        if len(tr) < 3 or len(en) < 3:
            return False
        
        # Kelime sayısı çok farklıysa reddet
        tr_words = len(tr.split())
        en_words = len(en.split())
        if abs(tr_words - en_words) > 3:
            return False
        
        # Uzunluk oranı çok farklıysa reddet
        ratio = len(tr) / len(en) if len(en) > 0 else 0
        if ratio < 0.3 or ratio > 3.0:
            return False
        
        # Her iki tarafın da anlamlı kelime içermesi gerekir
        tr_has_word = bool(re.search(r'[A-ZÇĞİÖŞÜa-zçğıöşü]{3,}', tr))
        en_has_word = bool(re.search(r'[A-Za-z]{3,}', en))
        if not tr_has_word or not en_has_word:
            return False
        
        return True
    
    def extract_consecutive_pairs(self, lines: List[str], page_num: int) -> List[Tuple[str, str]]:
        """Ardışık satırlardan TR/EN çiftleri çıkar"""
        pairs = []
        i = 0
        
        while i < len(lines) - 1:
            line1 = self.clean_term(lines[i])
            line2 = self.clean_term(lines[i + 1])
            
            # Boş satırları atla
            if not line1 or not line2:
                i += 1
                continue
            
            # Pattern 1: TR satırı + EN satırı
            if self.is_turkish_line(line1) and self.is_english_line(line2):
                if self.are_similar_terms(line1, line2):
                    pairs.append((line1.upper(), line2.upper()))
                    i += 2
                    continue
            
            # Pattern 2: EN satırı + TR satırı (bazı kataloglarda)
            if self.is_english_line(line1) and self.is_turkish_line(line2):
                if self.are_similar_terms(line2, line1):
                    pairs.append((line2.upper(), line1.upper()))
                    i += 2
                    continue
            
            i += 1
        
        return pairs
    
    def extract_table_pairs(self, lines: List[str], page_num: int) -> List[Tuple[str, str]]:
        """Tablo formatından TR/EN çiftleri çıkar
        Format: Parça No | TR Ad | EN Ad | Adet | ...
        """
        pairs = []
        
        for line in lines:
            # Slash ile ayrılmış çiftler: "PUL / WASHER"
            if ' / ' in line:
                parts = line.split(' / ')
                if len(parts) == 2:
                    tr = self.clean_term(parts[0])
                    en = self.clean_term(parts[1])
                    if tr and en and self.are_similar_terms(tr, en):
                        pairs.append((tr.upper(), en.upper()))
        
        return pairs
    
    def extract_from_page(self, page_num: int) -> List[Tuple[str, str]]:
        """Bir sayfadan tüm terim çiftlerini çıkar"""
        page = self.doc[page_num]
        text = page.get_text("text")
        
        # Satırlara böl
        lines = [l.strip() for l in text.split('\n') if l.strip()]
        
        pairs = []
        
        # Ardışık satır çiftleri
        pairs.extend(self.extract_consecutive_pairs(lines, page_num))
        
        # Tablo formatı
        pairs.extend(self.extract_table_pairs(lines, page_num))
        
        return pairs
    
    def extract_all(self, max_pages: Optional[int] = None) -> Dict[str, str]:
        """Tüm PDF'den terimleri çıkar"""
        total_pages = self.doc.page_count
        if max_pages:
            total_pages = min(total_pages, max_pages)
        
        print(f"📚 Toplam {total_pages} sayfa taranıyor...")
        
        for page_num in range(total_pages):
            pairs = self.extract_from_page(page_num)
            
            for tr, en in pairs:
                if tr not in self.terms:
                    self.terms[tr] = en
                    self.term_sources[tr].append(page_num + 1)
                elif self.terms[tr] != en:
                    # Farklı çeviri - daha uzun olanı tercih et
                    if len(en) > len(self.terms[tr]):
                        self.terms[tr] = en
        
        print(f"✅ {len(self.terms)} benzersiz terim çifti bulundu")
        return self.terms
    
    def get_statistics(self) -> Dict:
        """İstatistikleri döndür"""
        if not self.terms:
            return {}
        
        return {
            'total_terms': len(self.terms),
            'avg_tr_length': sum(len(t) for t in self.terms.keys()) / len(self.terms),
            'avg_en_length': sum(len(t) for t in self.terms.values()) / len(self.terms),
            'multi_word_terms': sum(1 for t in self.terms.keys() if ' ' in t),
            'single_word_terms': sum(1 for t in self.terms.keys() if ' ' not in t),
        }
    
    def export_json(self, output_path: str):
        """JSON formatında dışa aktar"""
        data = {
            'source': Path(self.pdf_path).name,
            'total_terms': len(self.terms),
            'terms': [
                {
                    'tr': tr,
                    'en': en,
                    'pages': self.term_sources.get(tr, [])
                }
                for tr, en in sorted(self.terms.items())
            ]
        }
        
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        
        print(f"📁 JSON kaydedildi: {output_path}")
    
    def export_csv(self, output_path: str):
        """CSV formatında dışa aktar"""
        import csv
        
        with open(output_path, 'w', encoding='utf-8', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(['Türkçe', 'İngilizce', 'Sayfalar'])
            
            for tr, en in sorted(self.terms.items()):
                pages = ','.join(map(str, self.term_sources.get(tr, [])))
                writer.writerow([tr, en, pages])
        
        print(f"📁 CSV kaydedildi: {output_path}")
    
    def close(self):
        """PDF'i kapat"""
        self.doc.close()


def main():
    """Ana fonksiyon"""
    import sys
    
    # Test PDF
    pdf_path = "/mnt/pdfs/İŞ MAKİNASI GRUBU/HİDROMEK/KAZICI YÜKLEYİCİ/HMK 102-B MAESTRO/HMK 102B MAESTRO Loader A700LH(PERKINS-TR3+ZF+ZF+HUSCO).pdf"
    
    if len(sys.argv) > 1:
        pdf_path = sys.argv[1]
    
    print(f"📄 PDF: {Path(pdf_path).name}")
    print("="*80)
    
    extractor = BilingualTermExtractor(pdf_path)
    
    # İlk 50 sayfadan çıkar (test için)
    terms = extractor.extract_all(max_pages=50)
    
    # İstatistikler
    stats = extractor.get_statistics()
    print("\n📊 İstatistikler:")
    for key, value in stats.items():
        print(f"   {key}: {value:.2f}" if isinstance(value, float) else f"   {key}: {value}")
    
    # Örnek terimler
    print("\n📝 Örnek Terimler (ilk 30):")
    print("-"*60)
    for i, (tr, en) in enumerate(sorted(terms.items())[:30]):
        print(f"{i+1:3}. {tr:<40} → {en}")
    
    # Dışa aktarım
    output_dir = Path("/var/www/html/PEPCVSON/chatbot/extracted_terms")
    output_dir.mkdir(exist_ok=True)
    
    base_name = Path(pdf_path).stem[:50]  # İlk 50 karakter
    
    extractor.export_json(str(output_dir / f"{base_name}_terms.json"))
    extractor.export_csv(str(output_dir / f"{base_name}_terms.csv"))
    
    extractor.close()
    
    print("\n✅ İşlem tamamlandı!")


if __name__ == "__main__":
    main()

