"""
API Routes für User Alert Subscriptions.

Verwaltet Nutzer-Abonnements für Templates und Digest-Einstellungen.

Endpoints:
- POST /subscriptions - Neue Subscription erstellen
- GET /subscriptions - User-Subscriptions auflisten
- GET /subscriptions/{id} - Subscription-Details
- PUT /subscriptions/{id} - Subscription aktualisieren
- DELETE /subscriptions/{id} - Subscription deaktivieren
- POST /subscriptions/{id}/activate-template - Template aktivieren
"""

import uuid
from typing import Optional, List
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session as DBSession

from ..db.database import get_db
from ..db.models import (
    UserAlertSubscriptionDB, AlertTemplateDB, AlertProfileDB,
    AlertTopicDB, AlertRuleDB, AlertModeEnum, UserRoleEnum
)


router = APIRouter(prefix="/subscriptions", tags=["subscriptions"])


# ============================================================================
# Request/Response Models
# ============================================================================

class SubscriptionCreate(BaseModel):
    """Request für neue Subscription."""
    mode: str = Field(default="guided", description="'guided' oder 'expert'")
    user_role: Optional[str] = Field(default=None, description="lehrkraft, schulleitung, it_beauftragte")
    template_ids: List[str] = Field(default=[], description="Ausgewählte Template-IDs (max. 3)")
    notification_email: Optional[str] = Field(default=None)
    digest_enabled: bool = Field(default=True)
    digest_frequency: str = Field(default="weekly")


class SubscriptionUpdate(BaseModel):
    """Request für Subscription-Update."""
    template_ids: Optional[List[str]] = None
    notification_email: Optional[str] = None
    digest_enabled: Optional[bool] = None
    digest_frequency: Optional[str] = None
    is_active: Optional[bool] = None


class SubscriptionResponse(BaseModel):
    """Response für eine Subscription."""
    id: str
    user_id: str
    mode: str
    user_role: Optional[str]
    selected_template_ids: List[str]
    template_names: List[str]
    notification_email: Optional[str]
    digest_enabled: bool
    digest_frequency: str
    wizard_completed: bool
    is_active: bool
    created_at: datetime
    updated_at: datetime


class SubscriptionListResponse(BaseModel):
    """Response für Subscription-Liste."""
    subscriptions: List[SubscriptionResponse]
    total: int


class ActivateTemplateRequest(BaseModel):
    """Request für Template-Aktivierung."""
    create_topics: bool = Field(default=True, description="Topics aus Template-Config erstellen")
    create_rules: bool = Field(default=True, description="Rules aus Template-Config erstellen")


class ActivateTemplateResponse(BaseModel):
    """Response für Template-Aktivierung."""
    status: str
    topics_created: int
    rules_created: int
    profile_updated: bool
    message: str


# ============================================================================
# Helper Functions
# ============================================================================

def get_user_id_from_request() -> str:
    """
    Extrahiert User-ID aus Request.
    TODO: JWT-Token auswerten, aktuell Dummy.
    """
    return "demo-user"


def _get_template_names(db: DBSession, template_ids: List[str]) -> List[str]:
    """Hole Template-Namen für IDs."""
    if not template_ids:
        return []
    templates = db.query(AlertTemplateDB).filter(
        AlertTemplateDB.id.in_(template_ids)
    ).all()
    return [t.name for t in templates]


def _subscription_to_response(sub: UserAlertSubscriptionDB, db: DBSession) -> SubscriptionResponse:
    """Konvertiere DB-Model zu Response."""
    template_ids = sub.selected_template_ids or []
    return SubscriptionResponse(
        id=sub.id,
        user_id=sub.user_id,
        mode=sub.mode.value if sub.mode else "guided",
        user_role=sub.user_role.value if sub.user_role else None,
        selected_template_ids=template_ids,
        template_names=_get_template_names(db, template_ids),
        notification_email=sub.notification_email,
        digest_enabled=sub.digest_enabled if sub.digest_enabled is not None else True,
        digest_frequency=sub.digest_frequency or "weekly",
        wizard_completed=sub.wizard_completed if sub.wizard_completed is not None else False,
        is_active=sub.is_active if sub.is_active is not None else True,
        created_at=sub.created_at,
        updated_at=sub.updated_at,
    )


# ============================================================================
# Endpoints
# ============================================================================

@router.post("", response_model=SubscriptionResponse)
async def create_subscription(
    request: SubscriptionCreate,
    db: DBSession = Depends(get_db)
):
    """
    Erstelle eine neue Alert-Subscription.

    Im Guided Mode werden 1-3 Templates ausgewählt.
    Im Expert Mode wird ein eigenes Profil konfiguriert.
    """
    user_id = get_user_id_from_request()

    # Validiere Modus
    try:
        mode = AlertModeEnum(request.mode)
    except ValueError:
        raise HTTPException(status_code=400, detail="Ungültiger Modus. Erlaubt: 'guided', 'expert'")

    # Validiere Rolle
    user_role = None
    if request.user_role:
        try:
            user_role = UserRoleEnum(request.user_role)
        except ValueError:
            raise HTTPException(
                status_code=400,
                detail="Ungültige Rolle. Erlaubt: 'lehrkraft', 'schulleitung', 'it_beauftragte'"
            )

    # Validiere Template-IDs
    if request.template_ids:
        if len(request.template_ids) > 3:
            raise HTTPException(status_code=400, detail="Maximal 3 Templates erlaubt")

        # Prüfe ob Templates existieren
        existing = db.query(AlertTemplateDB).filter(
            AlertTemplateDB.id.in_(request.template_ids)
        ).count()
        if existing != len(request.template_ids):
            raise HTTPException(status_code=400, detail="Eine oder mehrere Template-IDs sind ungültig")

    # Erstelle Subscription
    subscription = UserAlertSubscriptionDB(
        id=str(uuid.uuid4()),
        user_id=user_id,
        mode=mode,
        user_role=user_role,
        selected_template_ids=request.template_ids,
        notification_email=request.notification_email,
        digest_enabled=request.digest_enabled,
        digest_frequency=request.digest_frequency,
        wizard_completed=len(request.template_ids) > 0,  # Abgeschlossen wenn Templates gewählt
        is_active=True,
    )

    db.add(subscription)
    db.commit()
    db.refresh(subscription)

    return _subscription_to_response(subscription, db)


@router.get("", response_model=SubscriptionListResponse)
async def list_subscriptions(
    active_only: bool = Query(True, description="Nur aktive Subscriptions"),
    db: DBSession = Depends(get_db)
):
    """Liste alle Subscriptions des aktuellen Users."""
    user_id = get_user_id_from_request()

    query = db.query(UserAlertSubscriptionDB).filter(
        UserAlertSubscriptionDB.user_id == user_id
    )

    if active_only:
        query = query.filter(UserAlertSubscriptionDB.is_active == True)

    subscriptions = query.order_by(UserAlertSubscriptionDB.created_at.desc()).all()

    return SubscriptionListResponse(
        subscriptions=[_subscription_to_response(s, db) for s in subscriptions],
        total=len(subscriptions)
    )


@router.get("/{subscription_id}", response_model=SubscriptionResponse)
async def get_subscription(
    subscription_id: str,
    db: DBSession = Depends(get_db)
):
    """Hole Details einer Subscription."""
    user_id = get_user_id_from_request()

    subscription = db.query(UserAlertSubscriptionDB).filter(
        UserAlertSubscriptionDB.id == subscription_id,
        UserAlertSubscriptionDB.user_id == user_id
    ).first()

    if not subscription:
        raise HTTPException(status_code=404, detail="Subscription nicht gefunden")

    return _subscription_to_response(subscription, db)


@router.put("/{subscription_id}", response_model=SubscriptionResponse)
async def update_subscription(
    subscription_id: str,
    request: SubscriptionUpdate,
    db: DBSession = Depends(get_db)
):
    """Aktualisiere eine Subscription."""
    user_id = get_user_id_from_request()

    subscription = db.query(UserAlertSubscriptionDB).filter(
        UserAlertSubscriptionDB.id == subscription_id,
        UserAlertSubscriptionDB.user_id == user_id
    ).first()

    if not subscription:
        raise HTTPException(status_code=404, detail="Subscription nicht gefunden")

    # Update Felder
    if request.template_ids is not None:
        if len(request.template_ids) > 3:
            raise HTTPException(status_code=400, detail="Maximal 3 Templates erlaubt")
        subscription.selected_template_ids = request.template_ids

    if request.notification_email is not None:
        subscription.notification_email = request.notification_email

    if request.digest_enabled is not None:
        subscription.digest_enabled = request.digest_enabled

    if request.digest_frequency is not None:
        subscription.digest_frequency = request.digest_frequency

    if request.is_active is not None:
        subscription.is_active = request.is_active

    subscription.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(subscription)

    return _subscription_to_response(subscription, db)


@router.delete("/{subscription_id}")
async def deactivate_subscription(
    subscription_id: str,
    db: DBSession = Depends(get_db)
):
    """Deaktiviere eine Subscription (Soft-Delete)."""
    user_id = get_user_id_from_request()

    subscription = db.query(UserAlertSubscriptionDB).filter(
        UserAlertSubscriptionDB.id == subscription_id,
        UserAlertSubscriptionDB.user_id == user_id
    ).first()

    if not subscription:
        raise HTTPException(status_code=404, detail="Subscription nicht gefunden")

    subscription.is_active = False
    subscription.updated_at = datetime.utcnow()
    db.commit()

    return {"status": "success", "message": "Subscription deaktiviert"}


@router.post("/{subscription_id}/activate-template", response_model=ActivateTemplateResponse)
async def activate_template(
    subscription_id: str,
    request: ActivateTemplateRequest = None,
    db: DBSession = Depends(get_db)
):
    """
    Aktiviere die gewählten Templates für eine Subscription.

    Erstellt:
    - Topics aus Template.topics_config (RSS-Feeds)
    - Rules aus Template.rules_config (Filter-Regeln)
    - Aktualisiert das User-Profil mit Template.profile_config
    """
    user_id = get_user_id_from_request()

    subscription = db.query(UserAlertSubscriptionDB).filter(
        UserAlertSubscriptionDB.id == subscription_id,
        UserAlertSubscriptionDB.user_id == user_id
    ).first()

    if not subscription:
        raise HTTPException(status_code=404, detail="Subscription nicht gefunden")

    if not subscription.selected_template_ids:
        raise HTTPException(status_code=400, detail="Keine Templates ausgewählt")

    # Lade Templates
    templates = db.query(AlertTemplateDB).filter(
        AlertTemplateDB.id.in_(subscription.selected_template_ids)
    ).all()

    topics_created = 0
    rules_created = 0
    profile_updated = False

    for template in templates:
        # Topics erstellen
        if request is None or request.create_topics:
            for topic_config in (template.topics_config or []):
                topic = AlertTopicDB(
                    id=str(uuid.uuid4()),
                    user_id=user_id,
                    name=topic_config.get("name", f"Topic from {template.name}"),
                    description=f"Automatisch erstellt aus Template: {template.name}",
                    is_active=True,
                    fetch_interval_minutes=60,
                )
                db.add(topic)
                topics_created += 1

        # Rules erstellen
        if request is None or request.create_rules:
            for rule_config in (template.rules_config or []):
                rule = AlertRuleDB(
                    id=str(uuid.uuid4()),
                    user_id=user_id,
                    name=rule_config.get("name", f"Rule from {template.name}"),
                    description=f"Automatisch erstellt aus Template: {template.name}",
                    conditions=rule_config.get("conditions", []),
                    action_type=rule_config.get("action_type", "keep"),
                    action_config=rule_config.get("action_config", {}),
                    priority=rule_config.get("priority", 50),
                    is_active=True,
                )
                db.add(rule)
                rules_created += 1

        # Profil aktualisieren
        if template.profile_config:
            profile = db.query(AlertProfileDB).filter(
                AlertProfileDB.user_id == user_id
            ).first()

            if not profile:
                profile = AlertProfileDB(
                    id=str(uuid.uuid4()),
                    user_id=user_id,
                    name=f"Profil für {user_id}",
                )
                db.add(profile)

            # Merge priorities
            existing_priorities = profile.priorities or []
            new_priorities = template.profile_config.get("priorities", [])
            for p in new_priorities:
                if p not in existing_priorities:
                    existing_priorities.append(p)
            profile.priorities = existing_priorities

            # Merge exclusions
            existing_exclusions = profile.exclusions or []
            new_exclusions = template.profile_config.get("exclusions", [])
            for e in new_exclusions:
                if e not in existing_exclusions:
                    existing_exclusions.append(e)
            profile.exclusions = existing_exclusions

            profile_updated = True

    # Markiere Wizard als abgeschlossen
    subscription.wizard_completed = True
    subscription.updated_at = datetime.utcnow()

    db.commit()

    return ActivateTemplateResponse(
        status="success",
        topics_created=topics_created,
        rules_created=rules_created,
        profile_updated=profile_updated,
        message=f"Templates aktiviert: {topics_created} Topics, {rules_created} Rules erstellt."
    )
