from flask import abort, session, redirect, url_for
from models.user import User
from extensions import db
from functools import wraps
from services import auth_service

def login_user(user: User):
    """Log in the user by storing their ID in the session."""
    session['user_id'] = user.id
    session['is_admin'] = user.is_admin() # user / admin

def logout_user():
    """Log out the user by removing their ID from the session."""
    session.pop('user_id', None)

def current_user() -> User | None:
    """Return the User object of the currently logged-in user, or None if not logged in."""
    user_id = session.get('user_id')
    if not user_id:
        return None
    return User.query.get(user_id)

def is_logged_in() -> bool:
    """Return True if a user is currently logged in, False otherwise."""
    user_id = session.get('user_id')
    if user_id is None:
        return False

    user = User.query.get(user_id)
    if user is None:
        session.pop('user_id', None)
        return False

    return True

def is_admin():
    try:
        user = auth_service.current_user()
        return user.is_admin() # user / admin
    except:
        return False

        

def create_user_if_not_exists(email: str, phone: str = None, password: str = None) -> User:
    """
    Create a new user if the given email or phone does not exist.
    If a user with the given email or phone already exists, return that user.
    """
    user = None
    if email is not None:
        user = User.query.filter_by(email=email).first()
    elif phone is not None:
        user = User.query.filter_by(phone=phone).first()
    else:
        return None

    if user:
        return user  # User already exists

    # Create a new user
    new_user = User(email=email, phone=phone)
    if password:
        new_user.set_password(password)  # Hash the password
    db.session.add(new_user)
    db.session.commit()
    return new_user

def login_required(redirect_endpoint="login_register.login"):
    def decorator(function):
        @wraps(function)  # ✅ This preserves the original function name and endpoint
        def wrapper(*args, **kwargs):
            if is_logged_in():
                return function(*args, **kwargs)
            else:
                return redirect(url_for(redirect_endpoint))
        return wrapper
    return decorator


def not_login_required(redirect_endpoint="login_register.login"):
    def decorator(function):
        def wrapper(*args, **kwargs):
            if not is_logged_in():
                return function(*args, **kwargs)
            else:
                return redirect(url_for(redirect_endpoint))
        return wrapper
    return decorator





def admin_login_required():
    def decorator(function):
        @wraps(function)  # ✅ This preserves the original function name and endpoint
        def wrapper(*args, **kwargs):
            if is_admin():
                return function(*args, **kwargs)
            else:
                abort(403)   # این باعث می‌شود 403.html نمایش داده شود
        return wrapper
    return decorator
