"""
User-related views – migrated from core/views.py

Covers authentication, password management, and user settings (Einstellungen).
"""

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout, update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils import timezone
from django.views.decorators.http import require_POST

from app_admin.mixins import normale_user_required
from django.core.mail import EmailMultiAlternatives
from app_admin.mixins import reu_person_access_required
from django.template.loader import render_to_string
from app_nutzer.models import User
from app_admin.models import AdminUser
from core.services.anmeldungen import protokolliere_anmeldung

# ---------------------------------------------------------------------------
# Auth views
# ---------------------------------------------------------------------------

def login_view(request):
    """GET /login – show login form."""
    if request.user.is_authenticated:
        return redirect('/')
    return render(request, 'users/login.html')


def authenticate_view(request):
    """POST /users/authenticate – perform login."""
    if request.method != 'POST':
        return redirect('/login')
    email = request.POST.get('email', '').strip()
    password = request.POST.get('password', '')
    if not email or not password:
        return render(request, 'users/login.html', {
            'errors': {'email': 'E-Mail und Passwort sind erforderlich.'},
            'old': request.POST,
        })
    
    user = authenticate(request, username=email, password=password)

    # AdminUser ablehnen – kein Hinweis warum
    if isinstance(user, AdminUser):
        user = None

    if user is not None:
        login(request, user)
        User.objects.filter(PersonenID=user.PersonenID).update(
            last_login=timezone.now(),
            last_login_ip=request.META.get('REMOTE_ADDR', ''),
        )
        protokolliere_anmeldung(request, user)
        messages.success(request, 'Anmeldung erfolgreich durchgeführt')
        return redirect('/')
    else:
        # Fehlversuch nur protokollieren, wenn die E-Mail einem Nutzer gehoert
        bekannter_user = User.objects.filter(email__iexact=email).first()
        if bekannter_user is not None:
            protokolliere_anmeldung(request, bekannter_user, erfolgreich=False)
        return render(request, 'users/login.html', {
            'errors': {'email': 'Ungültige Anmeldedaten'},
            'old': request.POST,
        })


@require_POST
@login_required
def logout_view(request):
    """POST /logout – log out user."""
    logout(request)
    messages.success(request, 'Benutzer wurde erfolgreich abgemeldet')
    return redirect('/login')


# ---------------------------------------------------------------------------
# Password management views
# ---------------------------------------------------------------------------

def forgot_password_form(request):
    """GET/POST /forgot-pw-form – show form or send reset link."""
    if request.method != 'POST':
        return render(request, 'users/forgot_pw_form.html')

    email = request.POST.get('email', '').strip()
    if not email:
        return render(request, 'users/forgot_pw_form.html', {'error': 'E-Mail-Adresse ist erforderlich.'})

    try:
        user = User.objects.get(email=email)
        from django.contrib.auth.tokens import default_token_generator
        from django.core.mail import send_mail
        from django.conf import settings

        token = default_token_generator.make_token(user)
        reset_url = request.build_absolute_uri(f'/reset-password/{token}?email={email}')
        # Plain-text Fallback (wichtig für E-Mail-Clients ohne HTML-Support)
        text_content = f'Klicken Sie auf den folgenden Link, um Ihr Passwort zurückzusetzen:\n\n{reset_url}'

        # HTML aus deiner Vorlage
        html_content = render_to_string('users/reset_pw_email.html', {
            'reset_url': reset_url,
            'user': user,
        })

        email = EmailMultiAlternatives(
            subject='Passwort zurücksetzen',
            body=text_content,          # Plain-text als Basis
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[email],
        )
        email.attach_alternative(html_content, "text/html")  # HTML anhängen
        email.send(fail_silently=False)
    except User.DoesNotExist:
        pass  # Silent to prevent email enumeration

    messages.success(request, 'Falls ein Konto mit dieser E-Mail existiert, wurde ein Reset-Link gesendet.')
    return redirect('/forgot-pw-form')


@login_required
@normale_user_required
def change_password(request):
    """POST /users/changepassword – change password."""
    if request.method != 'POST':
        return redirect('/einstellungen')

    current_password = request.POST.get('current_password', '')
    new_password = request.POST.get('new_password', '')
    new_password_confirmation = request.POST.get('new_password_confirmation', '')

    errors = {}
    if not current_password:
        errors['current_password'] = 'Das aktuelle Passwort muss eingegeben werden.'
    if not new_password or len(new_password) < 6 or len(new_password) > 25:
        errors['new_password'] = 'Das neue Passwort muss 6 bis 25 Zeichen enthalten.'
    elif new_password != new_password_confirmation:
        errors['new_password'] = 'Das neue Passwort stimmt nicht mit dessen Wiederholung überein.'
    elif not request.user.check_password(current_password):
        errors['current_password'] = 'Eingabe des Aktuellen Passworts war falsch.'
    elif request.user.check_password(new_password):
        errors['new_password'] = 'Das neue und das alte Passwort dürfen nicht identisch sein!'

    if errors:
        return render(request, 'einstellungen.html', {'errors': errors})

    request.user.set_password(new_password)
    request.user.save()
    update_session_auth_hash(request, request.user)
    messages.success(request, 'Password wurde erfolgreich geändert!')
    return redirect('/einstellungen')


def password_reset_confirm(request, token):
    """GET /reset-password/{token} – show reset form."""
    email = request.GET.get('email', '')
    return render(request, 'users/reset_pw.html', {'token': token, 'email': email})


def password_reset_submit(request):
    """POST /reset-password – perform password reset."""
    if request.method != 'POST':
        return redirect('/login')

    token = request.POST.get('token', '')
    email = request.POST.get('email', '')
    password = request.POST.get('password', '')
    password_confirmation = request.POST.get('password_confirmation', '')

    errors = {}
    if not token:
        errors['token'] = 'Token ist erforderlich.'
    if not email:
        errors['email'] = 'E-Mail ist erforderlich.'
    if len(password) < 8:
        errors['password'] = 'Passwort muss mindestens 8 Zeichen lang sein.'
    elif password != password_confirmation:
        errors['password'] = 'Passwörter stimmen nicht überein.'

    if errors:
        return render(request, 'users/reset_pw.html', {'token': token, 'email': email, 'errors': errors})

    from django.contrib.auth.tokens import default_token_generator
    try:
        user = User.objects.get(email=email)
        if default_token_generator.check_token(user, token):
            user.set_password(password)
            user.save()
            messages.success(request, 'Passwort wurde erfolgreich zurückgesetzt.')
            return redirect('/login')
        else:
            return render(request, 'users/reset_pw.html', {
                'token': token, 'email': email,
                'errors': {'email': 'Ungültiger oder abgelaufener Token.'}
            })
    except User.DoesNotExist:
        return render(request, 'users/reset_pw.html', {
            'token': token, 'email': email,
            'errors': {'email': 'Ungültige E-Mail-Adresse.'}
        })


# ---------------------------------------------------------------------------
# Settings view
# ---------------------------------------------------------------------------

@normale_user_required
@login_required
def einstellungen_view(request):
    """GET /einstellungen."""
    return render(request, 'einstellungen.html')



# ---------------------------------------------------------------------------
# Settings view
# ---------------------------------------------------------------------------


@reu_person_access_required
def nuzterdaten_view(request, reuid: int, nutzer_id: int):
    """GET /nutzerdaten/reu/<reuid>/nu/<nutzer_id>/"""
    from app_real_estate.models import RealEstateUnit
    from app_nutzer.models import ReuMietV

    from core.services.nutzungsverhaeltnisse import lade_verhaeltnisse

    reu = RealEstateUnit.objects.select_related('REID').filter(REUID=reuid).first()

    # Juengstes Verhaeltnis dieser Person in dieser Einheit - Mieter oder
    # Eigentuemer. lade_verhaeltnisse sortiert chronologisch.
    verhaeltnisse = lade_verhaeltnisse(
        personen_ids=[nutzer_id], reuids=[reuid], nur_aktive=False
    )
    verhaeltnis = verhaeltnisse[-1] if verhaeltnisse else None

    # mietv bleibt aus Kompatibilitaet erhalten (nutzerdaten_part_mietv.html)
    mietv = ReuMietV.objects.filter(REUID=reuid, MieterID=nutzer_id).first()

    return render(request, 'nutzerdaten.html', {
        'reu': reu,
        'mietv': mietv,
        'verhaeltnis': verhaeltnis,
        'reuid': reuid,
        'nutzer_id': nutzer_id,
    })
