"""
core/context_processors.py

Stellt Template-Kontext-Variablen für die Navbar bereit:
  accessible_reuids   – Liste aller REUID-Integer, auf die der User Zugriff hat
  accessible_reus     – Liste von Dicts für die Combobox (ein Eintrag je
                        Nutzungsverhältnis, Mieter wie Eigentümer)
  current_reuid       – Aktuell aktive REUID (aus URL oder erster zugänglicher)
  current_nutzer_id   – PersonenID des aktuellen Nutzers (aus URL oder eigene)
  is_admin_user       – True wenn AdminUser

Gemergt wird nicht hier, sondern in core.services.nutzungsverhaeltnisse.
"""

from app_admin.models import AdminUser
from app_admin.mixins import get_accessible_reuids
from core.services.nutzungsverhaeltnisse import (
    ART_EIGENTUEMER,
    lade_verhaeltnisse,
    verhaeltnisse_fuer_user,
)


def navbar_context(request):
    user = request.user
    if not getattr(user, 'is_authenticated', False):
        return {}

    is_admin = isinstance(user, AdminUser)

    if is_admin:
        # AdminUser sieht alle Verhältnisse, auch beendete – sonst fehlen ihm
        # genau die Fälle, die er prüfen soll.
        verhaeltnisse = lade_verhaeltnisse(nur_aktive=False)
    else:
        verhaeltnisse = verhaeltnisse_fuer_user(user)

    accessible_reus = _baue_eintraege(verhaeltnisse)

    if is_admin:
        reuids = get_accessible_reuids(user)
    else:
        reuids = list(dict.fromkeys(e['reuid'] for e in accessible_reus))

    # Aktuelle REUID / nutzer_id aus URL-kwargs
    current_reuid = None
    current_nutzer_id = None
    resolver = getattr(request, 'resolver_match', None)
    if resolver:
        current_reuid = resolver.kwargs.get('reuid')
        current_nutzer_id = resolver.kwargs.get('nutzer_id')

    # Fallback: erste zugängliche REUID
    if current_reuid is None:
        if accessible_reus:
            current_reuid = accessible_reus[0]['reuid']
        elif reuids:
            current_reuid = reuids[0]

    # Fallback nutzer_id
    if current_nutzer_id is None:
        if not is_admin:
            current_nutzer_id = getattr(user, 'PersonenID', None)
        elif accessible_reus:
            match = next(
                (r for r in accessible_reus if r['reuid'] == current_reuid),
                accessible_reus[0],
            )
            current_nutzer_id = match['nutzer_id']

    return {
        'accessible_reuids': reuids,
        'accessible_reus': accessible_reus,
        'current_reuid': current_reuid,
        'current_nutzer_id': current_nutzer_id,
        'is_admin_user': is_admin,
    }


# ---------------------------------------------------------------------------
# Aufbau der Combobox-Einträge
# ---------------------------------------------------------------------------

def _baue_eintraege(verhaeltnisse):
    """Baut aus Nutzungsverhältnissen die Dropdown-Einträge.

    Personen und Einheiten werden in je einer Abfrage nachgeladen (kein N+1).
    """
    if not verhaeltnisse:
        return []

    from app_nutzer.models import User as NutzerUser
    from app_real_estate.models import RealEstateUnit

    personen_ids = {nv.personen_id for nv in verhaeltnisse}
    reuids = {nv.reuid for nv in verhaeltnisse}

    personen = {
        u.PersonenID: u
        for u in NutzerUser.objects.filter(PersonenID__in=personen_ids)
    }
    reus = {
        r.REUID: r
        for r in RealEstateUnit.objects
        .filter(REUID__in=reuids)
        .select_related('REID')
    }

    eintraege = []
    for nv in verhaeltnisse:
        reu = reus.get(nv.reuid)
        reu_text = _reu_label(reu) if reu else f'REU {nv.reuid}'
        person_text = _person_label(personen.get(nv.personen_id), nv.personen_id)
        zeitraum = _zeitraum_label(nv)

        label = f'{reu_text} – {person_text}'
        if zeitraum:
            label = f'{label} ({zeitraum})'

        eintraege.append({
            'reuid': nv.reuid,
            'nutzer_id': nv.personen_id,
            'art': nv.art,
            'ist_eigentuemer': nv.ist_eigentuemer,
            'schluessel': nv.schluessel,
            'gueltig_von': nv.gueltig_von,
            'gueltig_bis': nv.gueltig_bis,
            'label': label,
        })
    return eintraege


def _person_label(person, personen_id):
    if person is None:
        return f'Nutzer {personen_id}'
    name = f"{person.firstname or ''} {person.lastname or ''}".strip()
    return name or person.companyname or f'Nutzer {personen_id}'


def _zeitraum_label(nv):
    """z.B. 'Eigentümer seit 01.11.2025' oder 'Mieter, 01.07.2023 – 31.10.2024'."""
    rolle = 'Eigentümer' if nv.art == ART_EIGENTUEMER else 'Mieter'
    von = nv.gueltig_von.strftime('%d.%m.%Y') if nv.gueltig_von else None
    bis = nv.gueltig_bis.strftime('%d.%m.%Y') if nv.gueltig_bis else None

    if von and bis:
        return f'{rolle}, {von} – {bis}'
    if von:
        return f'{rolle} seit {von}'
    if bis:
        return f'{rolle} bis {bis}'
    return rolle


def _reu_label(reu):
    """Formatiert ein lesbares Label für eine RealEstateUnit."""
    parts = []
    if reu.REUDesc:
        parts.append(reu.REUDesc)
    if reu.REID:
        addr = f"{reu.REID.Street or ''} {reu.REID.HouseNumber or ''}".strip()
        if reu.REID.City:
            addr = f"{addr}, {reu.REID.City}" if addr else reu.REID.City
        if addr:
            parts.append(addr)
    return ' – '.join(parts) if parts else f'REU {reu.REUID}'
