"""Wahlprogramm-Referenzsystem mit Zitaten und Seitenreferenzen."""

import json
import re
from pathlib import Path
from typing import Optional

# Wahlprogramm-Metadaten
WAHLPROGRAMME = {
    "CDU": {
        "file": "cdu-nrw-2022.pdf",
        "titel": "Machen, worauf es ankommt",
        "partei": "CDU NRW",
        "jahr": 2022,
        "seiten": 109,
    },
    "SPD": {
        "file": "spd-nrw-2022.pdf",
        "titel": "Unser Land von morgen",
        "partei": "SPD NRW",
        "jahr": 2022,
        "seiten": 116,
    },
    "GRÜNE": {
        "file": "gruene-nrw-2022.pdf",
        "titel": "Von hier an Zukunft",
        "partei": "BÜNDNIS 90/DIE GRÜNEN NRW",
        "jahr": 2022,
        "seiten": 100,
    },
    "FDP": {
        "file": "fdp-nrw-2022.pdf",
        "titel": "Nie gab es mehr zu tun",
        "partei": "FDP NRW",
        "jahr": 2022,
        "seiten": 96,
    },
    "AfD": {
        "file": "afd-nrw-2022.pdf",
        "titel": "Wer sonst.",
        "partei": "AfD NRW",
        "jahr": 2022,
        "seiten": 68,
    },
}

# Basis-Pfad für Referenzdokumente
REFERENZEN_PATH = Path(__file__).parent / "static" / "referenzen"
KONTEXT_PATH = Path(__file__).parent / "kontext"


def load_wahlprogramm_text(partei: str) -> dict[int, str]:
    """Lädt Wahlprogramm-Text mit Seitenzuordnung.
    
    Returns:
        Dict mit Seitennummer -> Text
    """
    if partei not in WAHLPROGRAMME:
        return {}
    
    # Versuche paged-Textdatei zu laden
    paged_file = KONTEXT_PATH / f"{WAHLPROGRAMME[partei]['file'].replace('.pdf', '-paged.txt')}"
    if not paged_file.exists():
        # Fallback: Normale Textdatei
        txt_file = KONTEXT_PATH / f"{WAHLPROGRAMME[partei]['file'].replace('.pdf', '.txt')}"
        if txt_file.exists():
            return {1: txt_file.read_text()}
        return {}
    
    text = paged_file.read_text()
    pages = {}
    current_page = 1
    current_text = []
    
    for line in text.split('\n'):
        if line.startswith('--- PAGE '):
            # Speichere vorherige Seite
            if current_text:
                pages[current_page] = '\n'.join(current_text)
            # Extrahiere neue Seitenzahl
            match = re.search(r'PAGE (\d+)', line)
            if match:
                current_page = int(match.group(1))
            current_text = []
        else:
            current_text.append(line)
    
    # Letzte Seite speichern
    if current_text:
        pages[current_page] = '\n'.join(current_text)
    
    return pages


def search_wahlprogramm(partei: str, keywords: list[str], max_results: int = 3) -> list[dict]:
    """Sucht relevante Passagen in einem Wahlprogramm.
    
    Args:
        partei: Partei-Kürzel (CDU, SPD, GRÜNE, FDP, AfD)
        keywords: Suchbegriffe
        max_results: Maximale Anzahl Ergebnisse
        
    Returns:
        Liste von {seite, text, score, url}
    """
    pages = load_wahlprogramm_text(partei)
    if not pages:
        return []
    
    results = []
    keywords_lower = [k.lower() for k in keywords]
    
    for page_num, text in pages.items():
        text_lower = text.lower()
        
        # Zähle Keyword-Treffer
        score = sum(1 for kw in keywords_lower if kw in text_lower)
        
        if score > 0:
            # Finde relevante Absätze (mit Keyword)
            paragraphs = text.split('\n\n')
            relevant_paragraphs = []
            
            for para in paragraphs:
                para_clean = para.strip()
                if len(para_clean) < 50:
                    continue
                para_lower = para_clean.lower()
                if any(kw in para_lower for kw in keywords_lower):
                    relevant_paragraphs.append(para_clean)
            
            if relevant_paragraphs:
                # Nimm den relevantesten Absatz (mit meisten Keywords)
                best_para = max(relevant_paragraphs, 
                               key=lambda p: sum(1 for kw in keywords_lower if kw in p.lower()))
                
                # Kürze auf ~300 Zeichen
                if len(best_para) > 300:
                    best_para = best_para[:297] + "..."
                
                results.append({
                    "partei": partei,
                    "seite": page_num,
                    "text": best_para,
                    "score": score,
                    "url": f"/static/referenzen/{WAHLPROGRAMME[partei]['file']}#page={page_num}",
                    "quelle": f"{WAHLPROGRAMME[partei]['partei']} Wahlprogramm {WAHLPROGRAMME[partei]['jahr']}, S. {page_num}"
                })
    
    # Sortiere nach Score, nimm Top-Ergebnisse
    results.sort(key=lambda x: x['score'], reverse=True)
    return results[:max_results]


def find_relevant_quotes(antrag_text: str, fraktionen: list[str]) -> dict[str, list[dict]]:
    """Findet relevante Zitate aus Wahlprogrammen für einen Antrag.
    
    Args:
        antrag_text: Volltext des Antrags
        fraktionen: Liste der Fraktionen (Antragsteller + Regierung)
        
    Returns:
        Dict mit Partei -> Liste von Zitaten
    """
    # Extrahiere Keywords aus Antrag (einfache Heuristik)
    # Entferne Stoppwörter und kurze Wörter
    stopwords = {'der', 'die', 'das', 'und', 'oder', 'für', 'mit', 'von', 'zu', 'auf', 
                 'ist', 'sind', 'wird', 'werden', 'hat', 'haben', 'ein', 'eine', 'einer',
                 'den', 'dem', 'des', 'im', 'in', 'an', 'bei', 'nach', 'über', 'unter',
                 'durch', 'als', 'auch', 'nur', 'noch', 'aber', 'wenn', 'dass', 'sich',
                 'nicht', 'wie', 'so', 'aus', 'zum', 'zur', 'vom', 'beim', 'seit', 'bis'}
    
    words = re.findall(r'\b[A-Za-zäöüÄÖÜß]{4,}\b', antrag_text)
    keywords = [w for w in words if w.lower() not in stopwords]
    
    # Zähle Worthäufigkeit
    word_freq = {}
    for w in keywords:
        w_lower = w.lower()
        word_freq[w_lower] = word_freq.get(w_lower, 0) + 1
    
    # Top-Keywords (häufigste)
    top_keywords = sorted(word_freq.keys(), key=lambda x: word_freq[x], reverse=True)[:15]
    
    # Suche in relevanten Wahlprogrammen
    quotes = {}
    
    # Immer Regierungsfraktionen einbeziehen
    parteien_to_search = set(fraktionen) | {"CDU", "GRÜNE"}
    
    for partei in parteien_to_search:
        if partei in WAHLPROGRAMME:
            found = search_wahlprogramm(partei, top_keywords, max_results=2)
            if found:
                quotes[partei] = found
    
    return quotes


def format_quote_for_prompt(quotes: dict[str, list[dict]]) -> str:
    """Formatiert Zitate für den LLM-Prompt."""
    if not quotes:
        return ""
    
    lines = ["\n## Relevante Passagen aus Wahlprogrammen\n"]
    lines.append("Nutze diese Originalzitate als Belege in deiner Bewertung:\n")
    
    for partei, zitate in quotes.items():
        for z in zitate:
            lines.append(f"### {z['quelle']}")
            lines.append(f'> "{z["text"]}"')
            lines.append("")
    
    return "\n".join(lines)
