from flask import Blueprint, render_template, redirect, url_for, request, flash, session, g
from functools import wraps
from app.models import db, User

auth_bp = Blueprint('auth', __name__, url_prefix='/auth')

def role_required(*roles):
    """Decorator to restrict access to specific user roles."""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not g.user:
                flash("Please sign in to access this page.", "error")
                return redirect(url_for('auth.login'))
            if g.user.role not in roles:
                flash("You do not have permission to view this resource.", "error")
                # Redirect to appropriate dashboard
                if g.user.role == 'admin':
                    return redirect(url_for('admin.dashboard'))
                elif g.user.role == 'emc':
                    return redirect(url_for('emc.dashboard'))
                elif g.user.role == 'caller':
                    return redirect(url_for('caller.dashboard'))
                return redirect(url_for('auth.login'))
            return f(*args, **kwargs)
        return decorated_function
    return decorator

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    if g.user:
        # Already logged in, redirect to correct landing
        if g.user.role == 'admin':
            return redirect(url_for('admin.dashboard'))
        elif g.user.role == 'emc':
            return redirect(url_for('emc.dashboard'))
        elif g.user.role == 'caller':
            return redirect(url_for('caller.dashboard'))

    if request.method == 'POST':
        username = request.form.get('username', '').strip()
        password = request.form.get('password', '')
        
        user = User.query.filter_by(username=username).first()
        
        if user and user.check_password(password):
            # Check account status
            if user.role == 'emc' and user.status == 'pending':
                flash("Your registration is pending approval by the administrator.", "warning")
                return render_template('auth/login.html')
            elif user.status == 'blocked':
                flash("Your account has been suspended/blocked. Please contact support.", "error")
                return render_template('auth/login.html')
                
            # Valid session
            session.clear()
            session['user_id'] = user.id
            flash(f"Welcome back, {user.username}!", "success")
            
            if user.role == 'admin':
                return redirect(url_for('admin.dashboard'))
            elif user.role == 'emc':
                return redirect(url_for('emc.dashboard'))
            elif user.role == 'caller':
                return redirect(url_for('caller.dashboard'))
        else:
            flash("Invalid username or password.", "error")
            
    return render_template('auth/login.html')

@auth_bp.route('/register', methods=['POST'])
def register():
    username = request.form.get('username', '').strip()
    password = request.form.get('password', '')
    role = request.form.get('role', 'caller')
    company_name = request.form.get('company_name', '').strip()
    
    if not username or not password:
        flash("Username and password are required.", "error")
        return redirect(url_for('auth.login'))
        
    existing_user = User.query.filter_by(username=username).first()
    if existing_user:
        flash("Username is already taken.", "error")
        return redirect(url_for('auth.login'))
        
    # Create new user
    new_user = User(
        username=username,
        role=role
    )
    new_user.set_password(password)
    
    if role == 'emc':
        new_user.status = 'pending'  # Needs approval
        new_user.company_name = company_name if company_name else f"{username} Events"
        flash("Registration submitted successfully! Please wait for Admin approval.", "success")
    else:
        new_user.status = 'approved' # Callers are approved immediately
        flash("Registration successful! You can now log in.", "success")
        
    db.session.add(new_user)
    db.session.commit()
    
    return redirect(url_for('auth.login'))

@auth_bp.route('/revert-admin')
def revert_admin():
    """End admin impersonation and restore the original admin session."""
    admin_id = session.get('admin_user_id')
    if not admin_id:
        flash("No active impersonation session to revert.", "warning")
        return redirect(url_for('auth.login'))

    session.pop('admin_user_id', None)
    session['user_id'] = admin_id
    flash("Returned to Admin panel successfully.", "success")
    return redirect(url_for('admin.dashboard'))

@auth_bp.route('/logout')
def logout():
    session.clear()
    flash("You have been signed out successfully.", "success")
    return redirect(url_for('auth.login'))
