from fastapi import Depends, Request
from fastapi.responses import RedirectResponse
from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer
from sqlalchemy.orm import Session

from config import SECRET_KEY, SESSION_COOKIE, SESSION_MAX_AGE
from database import SessionLocal

serializer = URLSafeTimedSerializer(SECRET_KEY)


class AuthRequired(Exception):
    """Wird geworfen wenn kein gueltiger Login vorliegt."""
    pass


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


def get_current_user(request: Request, db: Session = Depends(get_db)):
    from models.benutzer import Benutzer

    # Login-Seite nicht schuetzen
    if request.url.path in ("/login", "/logout"):
        return None

    token = request.cookies.get(SESSION_COOKIE)
    if not token:
        raise AuthRequired()

    try:
        data = serializer.loads(token, max_age=SESSION_MAX_AGE)
    except (BadSignature, SignatureExpired):
        raise AuthRequired()

    user = db.query(Benutzer).filter(Benutzer.id == data["user_id"]).first()
    if not user or not user.ist_aktiv:
        raise AuthRequired()

    return user


def get_optional_user(request: Request, db: Session = Depends(get_db)):
    from models.benutzer import Benutzer

    token = request.cookies.get(SESSION_COOKIE)
    if not token:
        return None

    try:
        data = serializer.loads(token, max_age=SESSION_MAX_AGE)
    except (BadSignature, SignatureExpired):
        return None

    return db.query(Benutzer).filter(Benutzer.id == data["user_id"]).first()


def create_session_token(user_id: int) -> str:
    return serializer.dumps({"user_id": user_id})
