from functools import wraps
from flask import request, Response, url_for, session, redirect
from werkzeug.security import check_password_hash
from modules.core.audit import audit_log
from modules.users.db import get_pool

# =========================
# Base authentication
# =========================

def authenticate():
    return redirect(url_for("auth.login_page"))

def get_current_user():

    email = session.get("user_email")
    if not email:
        return None

    sql = """
          SELECT id, username, email, user_role, active
          FROM app_users
          WHERE email = :1 \
          """

    pool = get_pool()

    with pool.acquire() as conn:
        with conn.cursor() as cur:
            cur.execute(sql, [email])
            row = cur.fetchone()

    if not row:
        return None

    return {
        "id": row[0],
        "username": row[1],
        "email": row[2],
        "role": row[3],
        "active": row[4]
    }


# =========================
# Decorators
# =========================

def requires_login(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        user = get_current_user()
        if not user:
            return authenticate()
        return f(*args, **kwargs)
    return wrapper


def requires_app_auth(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        user = get_current_user()

        if not user:
            return authenticate()

        role = (user.get("role") or "").strip().lower()

        if role not in ["user", "admin"]:
            return authenticate()

        audit_log("LOGIN_SUCCESS", f"user={user}")

        return f(*args, **kwargs)
    return wrapper


def requires_admin_auth(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        user = get_current_user()

        if not user:
            return authenticate()

        if user.get("role") != "admin":
            return authenticate()

        audit_log("LOGIN_ADMIN_SUCCESS", f"user={user}")

        return f(*args, **kwargs)
    return wrapper