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.beziehung import Beziehung
from models.gruppe import Gruppe, KontaktGruppe
from models.kontakt import Kontakt
from models.tag import TagKategorie
from services import kontakt_service

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


@router.get("", response_class=HTMLResponse)
async def liste(
    request: Request,
    seite: str = "1",
    buchstabe: str = None,
    q: str = None,
    ort: str = None,
    email: str = None,
    plz: str = None,
    betreuer: str = None,
    eigentuemer: str = None,
    gruppe: str = None,
    user=Depends(get_current_user),
    db: Session = Depends(get_db),
):
    seite_int = int(seite) if seite and seite.isdigit() else 1
    gruppe_id = int(gruppe) if gruppe and gruppe.isdigit() else None
    ergebnis = kontakt_service.liste(
        db, typ="organisation", seite=seite_int, sortierung="firmenname",
        buchstabe=buchstabe, freitext=q, ort=ort,
        email=email, plz=plz, betreuer=betreuer, eigentuemer=eigentuemer,
        gruppe_id=gruppe_id,
    )
    gruppen = db.query(Gruppe).order_by(Gruppe.name).all()

    # Mitarbeiter fuer jede sichtbare Org laden
    org_ids = [k.id for k in ergebnis["kontakte"]]
    mitarbeiter_pro_org = {org_id: [] for org_id in org_ids}

    if org_ids:
        bezs = (
            db.query(Beziehung)
            .options(joinedload(Beziehung.kontakt_a), joinedload(Beziehung.kontakt_b))
            .filter(
                (Beziehung.kontakt_b_id.in_(org_ids)) | (Beziehung.kontakt_a_id.in_(org_ids))
            )
            .all()
        )
        seen = set()
        for bez in bezs:
            for org_id in org_ids:
                if bez.kontakt_a_id == org_id or bez.kontakt_b_id == org_id:
                    partner, rolle = bez.partner_von(org_id)
                    if partner and partner.typ == "person":
                        key = (org_id, partner.id)
                        if key not in seen:
                            seen.add(key)
                            mitarbeiter_pro_org[org_id].append({"kontakt": partner, "rolle": rolle or bez.typ})

    return templates.TemplateResponse("pages/organisationen/liste.html", {
        "request": request,
        "user": user,
        "active_page": "organisationen",
        "ergebnis": ergebnis,
        "buchstabe": buchstabe,
        "q": q or "",
        "ort_filter": ort or "",
        "email_filter": email or "",
        "plz_filter": plz or "",
        "betreuer_filter": betreuer or "",
        "eigentuemer_filter": eigentuemer or "",
        "gruppe_id": gruppe_id,
        "gruppen": gruppen,
        "mitarbeiter_pro_org": mitarbeiter_pro_org,
    })


@router.get("/neu", response_class=HTMLResponse)
async def neu_formular(request: Request, user=Depends(get_current_user)):
    return templates.TemplateResponse("pages/kontakte/formular.html", {
        "request": request,
        "user": user,
        "active_page": "organisationen",
        "kontakt": None,
        "typ": "organisation",
    })


@router.post("/neu")
async def erstellen(request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    form = await request.form()
    daten = {k: v for k, v in form.items() if v and k not in ("typ", "blacklist_override")}
    daten["typ"] = "organisation"

    # Blacklist-Check (ausser bei Override)
    if not form.get("blacklist_override"):
        treffer = kontakt_service.blacklist_check(db, daten)
        if treffer:
            return templates.TemplateResponse("pages/kontakte/formular.html", {
                "request": request,
                "user": user,
                "active_page": "organisationen",
                "kontakt": None,
                "typ": "organisation",
                "blacklist_warnung": treffer,
                "formular_daten": daten,
            })

    kontakt = kontakt_service.erstellen(db, daten, erstellt_von=user.kuerzel)
    return RedirectResponse(url=f"/kontakte/{kontakt.id}", status_code=303)


@router.get("/{kontakt_id}", response_class=HTMLResponse)
async def detail(kontakt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    kontakt = kontakt_service.detail(db, kontakt_id)
    if not kontakt:
        return RedirectResponse(url="/organisationen", status_code=303)

    alle_kontakte = db.query(Kontakt).filter(Kontakt.ist_blacklisted == False).order_by(Kontakt.nachname, Kontakt.firmenname).all()
    alle_gruppen = db.query(Gruppe).order_by(Gruppe.name).all()
    zugeordnete_gruppen_ids = {kg.gruppe_id for kg in kontakt.gruppen}
    kategorien = db.query(TagKategorie).order_by(TagKategorie.sortierung, TagKategorie.name).all()

    return templates.TemplateResponse("pages/organisationen/detail.html", {
        "request": request,
        "user": user,
        "active_page": "organisationen",
        "kontakt": kontakt,
        "alle_kontakte": alle_kontakte,
        "alle_gruppen": alle_gruppen,
        "zugeordnete_gruppen_ids": zugeordnete_gruppen_ids,
        "kategorien": kategorien,
    })


@router.get("/{kontakt_id}/mitarbeiter", response_class=HTMLResponse)
async def mitarbeiter(kontakt_id: int, request: Request, user=Depends(get_current_user), db: Session = Depends(get_db)):
    """HTMX-Endpoint: Mitarbeiter einer Organisation laden."""
    beziehungen = (
        db.query(Beziehung)
        .options(joinedload(Beziehung.kontakt_a), joinedload(Beziehung.kontakt_b))
        .filter(
            (
                (Beziehung.kontakt_a_id == kontakt_id) |
                (Beziehung.kontakt_b_id == kontakt_id)
            )
        )
        .all()
    )

    mitarbeiter = []
    for bez in beziehungen:
        partner, rolle = bez.partner_von(kontakt_id)
        if partner and partner.typ == "person":
            mitarbeiter.append({"kontakt": partner, "rolle": rolle or bez.typ})

    return templates.TemplateResponse("components/mitarbeiter_liste.html", {
        "request": request,
        "mitarbeiter": mitarbeiter,
    })
