from datetime import datetime

from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session, joinedload

from dependencies import get_current_user, get_db
from models.aktivitaet import Aktivitaet
from models.benutzer import Benutzer
from models.kampagne import Kampagne
from models.kontakt import Kontakt
import search

router = APIRouter(prefix="/aktivitaeten")
templates = Jinja2Templates(directory="templates")


@router.get("", response_class=HTMLResponse)
async def liste(
    request: Request,
    seite: str = "1",
    art: str = None,
    status: str = None,
    von: str = None,
    bis: str = None,
    zugewiesen_an: str = None,
    kampagne_id: str = None,
    q: str = None,
    kontakt_q: str = None,
    user=Depends(get_current_user),
    db: Session = Depends(get_db),
):
    seite_int = int(seite) if seite and seite.isdigit() else 1
    kampagne_id_int = int(kampagne_id) if kampagne_id and kampagne_id.isdigit() else None
    query = db.query(Aktivitaet)

    if art:
        query = query.filter(Aktivitaet.art == art)

    if status:
        query = query.filter(Aktivitaet.status == status)

    if von:
        try:
            query = query.filter(Aktivitaet.datum >= datetime.fromisoformat(von))
        except ValueError:
            pass

    if bis:
        try:
            from datetime import timedelta
            bis_end = datetime.fromisoformat(bis) + timedelta(days=1)
            query = query.filter(Aktivitaet.datum < bis_end)
        except ValueError:
            pass

    if zugewiesen_an:
        query = query.filter(Aktivitaet.zugewiesen_an == zugewiesen_an)

    if kampagne_id_int:
        query = query.filter(Aktivitaet.kampagne_id == kampagne_id_int)

    if q:
        from sqlalchemy import or_
        like = f"%{q}%"
        query = query.filter(or_(
            Aktivitaet.betreff.ilike(like),
            Aktivitaet.bemerkung.ilike(like),
        ))

    if kontakt_q:
        from sqlalchemy import or_
        like = f"%{kontakt_q}%"
        query = query.join(Kontakt, Aktivitaet.kontakt_id == Kontakt.id).filter(or_(
            Kontakt.nachname.ilike(like),
            Kontakt.vorname.ilike(like),
            Kontakt.firmenname.ilike(like),
        ))

    gesamt = query.count()
    pro_seite = 50
    aktivitaeten = (
        query.order_by(Aktivitaet.datum.desc())
        .offset((seite_int - 1) * pro_seite)
        .limit(pro_seite)
        .all()
    )
    seiten = (gesamt + pro_seite - 1) // pro_seite

    benutzer = db.query(Benutzer).filter(Benutzer.ist_aktiv == True).order_by(Benutzer.name).all()
    alle_kampagnen = db.query(Kampagne).order_by(Kampagne.titel).all()

    return templates.TemplateResponse("pages/aktivitaeten/liste.html", {
        "request": request,
        "user": user,
        "active_page": "aktivitaeten",
        "aktivitaeten": aktivitaeten,
        "gesamt": gesamt,
        "seite": seite_int,
        "seiten": seiten,
        "art_filter": art,
        "status_filter": status,
        "von_filter": von,
        "bis_filter": bis,
        "zugewiesen_an_filter": zugewiesen_an,
        "kampagne_id_filter": kampagne_id_int,
        "q": q,
        "kontakt_q_filter": kontakt_q or "",
        "benutzer": benutzer,
        "alle_kampagnen": alle_kampagnen,
        "art_labels": Aktivitaet.ART_LABELS,
    })


@router.get("/neu", response_class=HTMLResponse)
async def neu_formular(
    request: Request,
    kontakt_id: int = None,
    veranstaltung_id: int = None,
    kampagne_id: int = None,
    user=Depends(get_current_user),
    db: Session = Depends(get_db),
):
    kontakte = db.query(Kontakt).order_by(Kontakt.nachname, Kontakt.vorname).all()
    benutzer = db.query(Benutzer).filter(Benutzer.ist_aktiv == True).order_by(Benutzer.name).all()
    projekte = [r[0] for r in db.query(Aktivitaet.projekt).filter(Aktivitaet.projekt.isnot(None)).distinct().order_by(Aktivitaet.projekt).all()]
    jetzt = datetime.now().strftime('%Y-%m-%dT%H:%M')
    return templates.TemplateResponse("pages/aktivitaeten/formular.html", {
        "request": request,
        "user": user,
        "active_page": "aktivitaeten",
        "aktivitaet": None,
        "kontakte": kontakte,
        "benutzer": benutzer,
        "kontakt_id": kontakt_id,
        "veranstaltung_id": veranstaltung_id,
        "kampagne_id": kampagne_id,
        "art_labels": Aktivitaet.ART_LABELS,
        "projekte": projekte,
        "jetzt": jetzt,
    })


@router.post("/neu")
async def erstellen(request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    form = await request.form()

    # Projekt: entweder aus Dropdown oder Freitext fuer neues Projekt
    projekt = form.get("projekt") or None
    if form.get("projekt_neu"):
        projekt = form.get("projekt_neu").strip() or projekt

    akt = Aktivitaet(
        kontakt_id=int(form["kontakt_id"]),
        art=form.get("art", "notiz"),
        betreff=form.get("betreff") or None,
        bemerkung=form.get("bemerkung") or None,
        status=form.get("status", "information"),
        projekt=projekt,
        zugewiesen_an=form.get("zugewiesen_an") or None,
        erfasst_von=user.kuerzel,
        aktualisiert_von=user.kuerzel,
    )

    # Optionale FK-Zuordnungen
    if form.get("veranstaltung_id"):
        akt.veranstaltung_id = int(form["veranstaltung_id"])
    if form.get("kampagne_id"):
        akt.kampagne_id = int(form["kampagne_id"])

    datum_str = form.get("datum")
    if datum_str:
        try:
            akt.datum = datetime.fromisoformat(datum_str)
        except ValueError:
            akt.datum = datetime.now()
    else:
        akt.datum = datetime.now()

    faellig_str = form.get("faellig_am")
    if faellig_str:
        try:
            akt.faellig_am = datetime.fromisoformat(faellig_str)
        except ValueError:
            pass

    db.add(akt)
    db.flush()
    search.index_aktivitaet(db, akt)
    db.commit()

    # Redirect: zurueck zur vorherigen Seite oder Aktivitaet-Detail
    next_url = form.get("next") or f"/aktivitaeten/{akt.id}"
    return RedirectResponse(url=next_url, status_code=303)


@router.post("/bulk")
async def bulk_erstellen(request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    """Erstellt je eine Aktivität pro ausgewähltem Kontakt."""
    form = await request.form()
    kontakt_ids = [int(i) for i in form.getlist("kontakt_ids") if i]
    art = form.get("art", "notiz")
    betreff = form.get("betreff") or None
    bemerkung = form.get("bemerkung") or None
    status = form.get("status", "erledigt")
    zugewiesen_an = form.get("zugewiesen_an") or None

    for kid in kontakt_ids:
        akt = Aktivitaet(
            kontakt_id=kid,
            art=art,
            betreff=betreff,
            bemerkung=bemerkung,
            status=status,
            zugewiesen_an=zugewiesen_an,
            datum=datetime.now(),
            erfasst_von=user.kuerzel,
            aktualisiert_von=user.kuerzel,
        )
        db.add(akt)
        db.flush()
        search.index_aktivitaet(db, akt)

    db.commit()
    return RedirectResponse(url="/recherche", status_code=303)


@router.get("/{akt_id}", response_class=HTMLResponse)
async def detail(akt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    akt = (
        db.query(Aktivitaet)
        .options(joinedload(Aktivitaet.kontakt), joinedload(Aktivitaet.dokumente))
        .filter(Aktivitaet.id == akt_id)
        .first()
    )
    if not akt:
        return RedirectResponse(url="/aktivitaeten", status_code=303)

    benutzer = db.query(Benutzer).filter(Benutzer.ist_aktiv == True).all()
    benutzer_map = {b.kuerzel: b.name for b in benutzer}

    return templates.TemplateResponse("pages/aktivitaeten/detail.html", {
        "request": request,
        "user": user,
        "active_page": "aktivitaeten",
        "aktivitaet": akt,
        "benutzer_map": benutzer_map,
    })


@router.get("/{akt_id}/bearbeiten", response_class=HTMLResponse)
async def bearbeiten_formular(akt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    akt = db.query(Aktivitaet).filter(Aktivitaet.id == akt_id).first()
    if not akt:
        return RedirectResponse(url="/aktivitaeten", status_code=303)

    kontakte = db.query(Kontakt).order_by(Kontakt.nachname, Kontakt.vorname).all()
    benutzer = db.query(Benutzer).filter(Benutzer.ist_aktiv == True).order_by(Benutzer.name).all()
    projekte = [r[0] for r in db.query(Aktivitaet.projekt).filter(Aktivitaet.projekt.isnot(None)).distinct().order_by(Aktivitaet.projekt).all()]
    return templates.TemplateResponse("pages/aktivitaeten/formular.html", {
        "request": request,
        "user": user,
        "active_page": "aktivitaeten",
        "aktivitaet": akt,
        "kontakte": kontakte,
        "benutzer": benutzer,
        "kontakt_id": akt.kontakt_id,
        "veranstaltung_id": akt.veranstaltung_id,
        "kampagne_id": akt.kampagne_id,
        "art_labels": Aktivitaet.ART_LABELS,
        "projekte": projekte,
        "jetzt": None,
    })


@router.post("/{akt_id}/bearbeiten")
async def aktualisieren(akt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    akt = db.query(Aktivitaet).filter(Aktivitaet.id == akt_id).first()
    if not akt:
        return RedirectResponse(url="/aktivitaeten", status_code=303)

    form = await request.form()
    akt.kontakt_id = int(form["kontakt_id"])
    akt.art = form.get("art", "notiz")
    akt.betreff = form.get("betreff") or None
    akt.bemerkung = form.get("bemerkung") or None
    akt.status = form.get("status", "information")
    # Projekt: entweder aus Dropdown oder Freitext fuer neues Projekt
    projekt = form.get("projekt") or None
    if form.get("projekt_neu"):
        projekt = form.get("projekt_neu").strip() or projekt
    akt.projekt = projekt
    akt.zugewiesen_an = form.get("zugewiesen_an") or None
    akt.aktualisiert_von = user.kuerzel
    if form.get("veranstaltung_id"):
        akt.veranstaltung_id = int(form["veranstaltung_id"])
    else:
        akt.veranstaltung_id = None
    if form.get("kampagne_id"):
        akt.kampagne_id = int(form["kampagne_id"])
    else:
        akt.kampagne_id = None

    datum_str = form.get("datum")
    if datum_str:
        try:
            akt.datum = datetime.fromisoformat(datum_str)
        except ValueError:
            pass

    faellig_str = form.get("faellig_am")
    if faellig_str:
        try:
            akt.faellig_am = datetime.fromisoformat(faellig_str)
        except ValueError:
            pass
    else:
        akt.faellig_am = None

    db.flush()
    search.index_aktivitaet(db, akt)
    db.commit()

    next_url = form.get("next") or f"/aktivitaeten/{akt.id}"
    return RedirectResponse(url=next_url, status_code=303)


@router.post("/{akt_id}/erledigt")
async def erledigt_toggle(akt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    akt = db.query(Aktivitaet).filter(Aktivitaet.id == akt_id).first()
    if akt:
        akt.status = "erledigt" if akt.status == "offen" else "offen"
        akt.aktualisiert_von = user.kuerzel
        db.commit()
    # Redirect zurück (Referer oder Aktivitäten-Liste)
    referer = request.headers.get("referer", "/aktivitaeten")
    return RedirectResponse(url=referer, status_code=303)


@router.get("/{akt_id}/loeschen")
async def loeschen(akt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    akt = db.query(Aktivitaet).filter(Aktivitaet.id == akt_id).first()
    if akt:
        db.delete(akt)
        db.commit()
    referer = request.headers.get("referer", "/aktivitaeten")
    return RedirectResponse(url=referer, status_code=303)
