from flask import Blueprint, request, jsonify, session
from datetime import datetime
from src.models.user import db, User
from src.models.company import Company

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/login', methods=['POST'])
def login():
    """Endpoint para autenticación de usuarios"""
    try:
        data = request.get_json()
        
        if not data or not data.get('username') or not data.get('password'):
            return jsonify({'error': 'Username y password son requeridos'}), 400
        
        username = data.get('username')
        password = data.get('password')
        
        # Buscar usuario por username o email
        user = User.query.filter(
            (User.username == username) | (User.email == username)
        ).first()
        
        if not user or not user.check_password(password):
            return jsonify({'error': 'Credenciales inválidas'}), 401
        
        if not user.is_active:
            return jsonify({'error': 'Usuario inactivo'}), 401
        
        # Actualizar último login
        user.last_login = datetime.utcnow()
        db.session.commit()
        
        # Crear sesión
        session['user_id'] = user.id
        session['user_role'] = user.role
        session['company_id'] = user.company_id
        
        # Obtener información de la empresa si aplica
        company_info = None
        if user.company_id:
            company = Company.query.get(user.company_id)
            if company:
                company_info = company.to_dict()
        
        return jsonify({
            'message': 'Login exitoso',
            'user': user.to_dict(),
            'company': company_info
        }), 200
        
    except Exception as e:
        return jsonify({'error': f'Error interno del servidor: {str(e)}'}), 500

@auth_bp.route('/logout', methods=['POST'])
def logout():
    """Endpoint para cerrar sesión"""
    try:
        session.clear()
        return jsonify({'message': 'Logout exitoso'}), 200
    except Exception as e:
        return jsonify({'error': f'Error interno del servidor: {str(e)}'}), 500

@auth_bp.route('/me', methods=['GET'])
def get_current_user():
    """Obtener información del usuario actual"""
    try:
        user_id = session.get('user_id')
        
        if not user_id:
            return jsonify({'error': 'No autenticado'}), 401
        
        user = User.query.get(user_id)
        if not user:
            return jsonify({'error': 'Usuario no encontrado'}), 404
        
        # Obtener información de la empresa si aplica
        company_info = None
        if user.company_id:
            company = Company.query.get(user.company_id)
            if company:
                company_info = company.to_dict()
        
        return jsonify({
            'user': user.to_dict(),
            'company': company_info
        }), 200
        
    except Exception as e:
        return jsonify({'error': f'Error interno del servidor: {str(e)}'}), 500

@auth_bp.route('/register', methods=['POST'])
def register():
    """Endpoint para registro de nuevos usuarios (solo super_admin puede crear usuarios)"""
    try:
        # Verificar que el usuario actual sea super_admin
        current_user_role = session.get('user_role')
        if current_user_role != 'super_admin':
            return jsonify({'error': 'No autorizado. Solo super administradores pueden crear usuarios'}), 403
        
        data = request.get_json()
        
        # Validar campos requeridos
        required_fields = ['username', 'email', 'password', 'first_name', 'last_name', 'role']
        for field in required_fields:
            if not data.get(field):
                return jsonify({'error': f'Campo {field} es requerido'}), 400
        
        # Validar que el rol sea válido
        valid_roles = ['super_admin', 'accountant', 'employee']
        if data.get('role') not in valid_roles:
            return jsonify({'error': f'Rol inválido. Debe ser uno de: {", ".join(valid_roles)}'}), 400
        
        # Verificar que username y email no existan
        existing_user = User.query.filter(
            (User.username == data.get('username')) | (User.email == data.get('email'))
        ).first()
        
        if existing_user:
            return jsonify({'error': 'Username o email ya existe'}), 409
        
        # Crear nuevo usuario
        new_user = User(
            username=data.get('username'),
            email=data.get('email'),
            first_name=data.get('first_name'),
            last_name=data.get('last_name'),
            phone=data.get('phone'),
            role=data.get('role'),
            company_id=data.get('company_id')
        )
        
        new_user.set_password(data.get('password'))
        
        db.session.add(new_user)
        db.session.commit()
        
        return jsonify({
            'message': 'Usuario creado exitosamente',
            'user': new_user.to_dict()
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': f'Error interno del servidor: {str(e)}'}), 500

def require_auth(f):
    """Decorador para requerir autenticación"""
    from functools import wraps
    
    @wraps(f)
    def decorated_function(*args, **kwargs):
        user_id = session.get('user_id')
        if not user_id:
            return jsonify({'error': 'Autenticación requerida'}), 401
        
        user = User.query.get(user_id)
        if not user or not user.is_active:
            return jsonify({'error': 'Usuario no válido o inactivo'}), 401
        
        return f(*args, **kwargs)
    
    return decorated_function

def require_role(required_role):
    """Decorador para requerir un rol específico"""
    def decorator(f):
        from functools import wraps
        
        @wraps(f)
        def decorated_function(*args, **kwargs):
            user_role = session.get('user_role')
            if user_role != required_role:
                return jsonify({'error': f'Rol {required_role} requerido'}), 403
            
            return f(*args, **kwargs)
        
        return decorated_function
    return decorator

