"""
Repository für Alert Profiles (Nutzer-Profile für Relevanz-Scoring).
"""
import uuid
from datetime import datetime
from typing import Optional, List, Dict, Any
from sqlalchemy.orm import Session as DBSession
from sqlalchemy.orm.attributes import flag_modified

from .models import AlertProfileDB


class ProfileRepository:
    """Repository für Alert Profiles (Nutzer-Profile für Relevanz-Scoring)."""

    def __init__(self, db: DBSession):
        self.db = db

    # ==================== CREATE / GET-OR-CREATE ====================

    def get_or_create(self, user_id: str = None) -> AlertProfileDB:
        """Holt oder erstellt ein Profil."""
        profile = self.get_by_user_id(user_id)
        if profile:
            return profile

        # Neues Profil erstellen
        profile = AlertProfileDB(
            id=str(uuid.uuid4()),
            user_id=user_id,
            name="Default" if not user_id else f"Profile {user_id[:8]}",
        )
        self.db.add(profile)
        self.db.commit()
        self.db.refresh(profile)
        return profile

    def create_default_education_profile(self, user_id: str = None) -> AlertProfileDB:
        """Erstellt ein Standard-Profil für Bildungsthemen."""
        profile = AlertProfileDB(
            id=str(uuid.uuid4()),
            user_id=user_id,
            name="Bildung Default",
            priorities=[
                {
                    "label": "Inklusion",
                    "weight": 0.9,
                    "keywords": ["inklusiv", "Förderbedarf", "Behinderung", "Barrierefreiheit"],
                    "description": "Inklusive Bildung, Förderschulen, Nachteilsausgleich"
                },
                {
                    "label": "Datenschutz Schule",
                    "weight": 0.85,
                    "keywords": ["DSGVO", "Schülerfotos", "Einwilligung", "personenbezogene Daten"],
                    "description": "DSGVO in Schulen, Datenschutz bei Klassenfotos"
                },
                {
                    "label": "Schulrecht Bayern",
                    "weight": 0.8,
                    "keywords": ["BayEUG", "Schulordnung", "Kultusministerium", "Bayern"],
                    "description": "Bayerisches Schulrecht, Verordnungen"
                },
                {
                    "label": "Digitalisierung Schule",
                    "weight": 0.7,
                    "keywords": ["DigitalPakt", "Tablet-Klasse", "Lernplattform"],
                    "description": "Digitale Medien im Unterricht"
                },
            ],
            exclusions=["Stellenanzeige", "Praktikum gesucht", "Werbung", "Pressemitteilung"],
            policies={
                "prefer_german_sources": True,
                "max_age_days": 30,
                "min_content_length": 100,
            }
        )
        self.db.add(profile)
        self.db.commit()
        self.db.refresh(profile)
        return profile

    # ==================== READ ====================

    def get_by_id(self, profile_id: str) -> Optional[AlertProfileDB]:
        """Holt ein Profil nach ID."""
        return self.db.query(AlertProfileDB).filter(
            AlertProfileDB.id == profile_id
        ).first()

    def get_by_user_id(self, user_id: str) -> Optional[AlertProfileDB]:
        """Holt ein Profil nach User-ID."""
        if not user_id:
            # Default-Profil ohne User
            return self.db.query(AlertProfileDB).filter(
                AlertProfileDB.user_id.is_(None)
            ).first()

        return self.db.query(AlertProfileDB).filter(
            AlertProfileDB.user_id == user_id
        ).first()

    # ==================== UPDATE ====================

    def update_priorities(
        self,
        profile_id: str,
        priorities: List[Dict],
    ) -> Optional[AlertProfileDB]:
        """Aktualisiert die Prioritäten eines Profils."""
        profile = self.get_by_id(profile_id)
        if not profile:
            return None

        profile.priorities = priorities
        self.db.commit()
        self.db.refresh(profile)
        return profile

    def update_exclusions(
        self,
        profile_id: str,
        exclusions: List[str],
    ) -> Optional[AlertProfileDB]:
        """Aktualisiert die Ausschlüsse eines Profils."""
        profile = self.get_by_id(profile_id)
        if not profile:
            return None

        profile.exclusions = exclusions
        self.db.commit()
        self.db.refresh(profile)
        return profile

    def add_feedback(
        self,
        profile_id: str,
        title: str,
        url: str,
        is_relevant: bool,
        reason: str = "",
    ) -> Optional[AlertProfileDB]:
        """Fügt Feedback als Beispiel hinzu."""
        profile = self.get_by_id(profile_id)
        if not profile:
            return None

        example = {
            "title": title,
            "url": url,
            "reason": reason,
            "added_at": datetime.utcnow().isoformat(),
        }

        if is_relevant:
            examples = list(profile.positive_examples or [])
            examples.append(example)
            profile.positive_examples = examples[-20:]  # Max 20
            profile.total_kept += 1
            flag_modified(profile, "positive_examples")
        else:
            examples = list(profile.negative_examples or [])
            examples.append(example)
            profile.negative_examples = examples[-20:]  # Max 20
            profile.total_dropped += 1
            flag_modified(profile, "negative_examples")

        profile.total_scored += 1
        self.db.commit()
        self.db.refresh(profile)
        return profile

    def update_stats(
        self,
        profile_id: str,
        kept: int = 0,
        dropped: int = 0,
    ) -> Optional[AlertProfileDB]:
        """Aktualisiert die Statistiken eines Profils."""
        profile = self.get_by_id(profile_id)
        if not profile:
            return None

        profile.total_scored += kept + dropped
        profile.total_kept += kept
        profile.total_dropped += dropped

        self.db.commit()
        self.db.refresh(profile)
        return profile

    # ==================== DELETE ====================

    def delete(self, profile_id: str) -> bool:
        """Löscht ein Profil."""
        profile = self.get_by_id(profile_id)
        if not profile:
            return False

        self.db.delete(profile)
        self.db.commit()
        return True

    # ==================== CONVERSION ====================

    def to_dict(self, profile: AlertProfileDB) -> Dict[str, Any]:
        """Konvertiert DB-Model zu Dictionary."""
        return {
            "id": profile.id,
            "user_id": profile.user_id,
            "name": profile.name,
            "priorities": profile.priorities,
            "exclusions": profile.exclusions,
            "policies": profile.policies,
            "examples": {
                "positive": len(profile.positive_examples or []),
                "negative": len(profile.negative_examples or []),
            },
            "stats": {
                "total_scored": profile.total_scored,
                "total_kept": profile.total_kept,
                "total_dropped": profile.total_dropped,
                "accuracy_estimate": profile.accuracy_estimate,
            },
            "created_at": profile.created_at.isoformat() if profile.created_at else None,
            "updated_at": profile.updated_at.isoformat() if profile.updated_at else None,
        }
