from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from app.database import db
from app.models import User, UserRole, BusinessApplicationStatus
from app.auth import get_current_user, require_super_admin
import re

users_bp = Blueprint('users', __name__)

def validate_phone(phone):
    """Validate phone number - only allow numbers and common phone symbols: +, -, spaces, parentheses"""
    if not phone:
        return True  # Allow empty phone (optional field)
    phone_regex = r'^[0-9+\-() ]+$'
    return bool(re.match(phone_regex, phone))

def validate_text(text):
    """Validate text - prevent dangerous characters like <, >, &, etc."""
    if not text:
        return True  # Allow empty text
    # Allow letters, numbers, spaces, and common safe characters
    text_regex = r'^[a-zA-Z0-9áéíóúÁÉÍÓÚñÑüÜ\s.,;:!?\-()/]+$'
    return bool(re.match(text_regex, text))

def user_to_dict(user):
    """Convert User model to dictionary."""
    return {
        'id': user.id,
        'email': user.email,
        'role': user.role.value,
        'business_id': user.business_id,
        'business_application_status': user.business_application_status.value if user.business_application_status else None,
        'created_at': user.created_at.isoformat() if user.created_at else None
    }

@users_bp.route('/me', methods=['GET'])
@jwt_required()
def get_my_profile():
    """Get current user's profile."""
    user = get_current_user()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    return jsonify(user_to_dict(user)), 200

@users_bp.route('/me', methods=['PUT'])
@jwt_required()
def update_my_profile():
    """Update current user's profile."""
    user = get_current_user()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    
    data = request.get_json()
    
    if 'email' in data:
        existing = User.query.filter_by(email=data['email']).filter(User.id != user.id).first()
        if existing:
            return jsonify({'error': 'Email already in use'}), 400
        user.email = data['email']
    
    if 'business_application_status' in data:
        user.business_application_status = BusinessApplicationStatus(data['business_application_status'])
    
    db.session.commit()
    
    return jsonify(user_to_dict(user)), 200

@users_bp.route('', methods=['GET'])
def get_all_users():
    """Get all users. Public endpoint (for public profiles)."""
    skip = request.args.get('skip', 0, type=int)
    limit = request.args.get('limit', 100, type=int)
    
    users = User.query.offset(skip).limit(limit).all()
    # Only return public information
    public_users = [{
        'id': u.id,
        'email': u.email,
        'role': u.role.value,
        'created_at': u.created_at.isoformat() if u.created_at else None
    } for u in users]
    return jsonify(public_users), 200

@users_bp.route('/<user_id>', methods=['GET'])
def get_user(user_id):
    """Get a specific user. Public endpoint (for public profiles)."""
    user = User.query.filter_by(id=user_id).first()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    # Only return public information
    return jsonify({
        'id': user.id,
        'email': user.email,
        'role': user.role.value,
        'created_at': user.created_at.isoformat() if user.created_at else None
    }), 200

@users_bp.route('/pending-business-applications', methods=['GET'])
@require_super_admin
def get_pending_business_applications():
    """Get all users with pending business applications. Super admin only."""
    pending_users = User.query.filter_by(
        estado_solicitud_negocio=BusinessApplicationStatus.PENDING
    ).all()
    
    return jsonify([user_to_dict(u) for u in pending_users]), 200

@users_bp.route('/<user_id>/approve-business', methods=['POST'])
@require_super_admin
def approve_business_application(user_id):
    """Approve a business application and create the business. Super admin only."""
    from app.models import TireBusiness
    import uuid
    
    user = User.query.filter_by(id=user_id).first()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    
    if user.estado_solicitud_negocio != BusinessApplicationStatus.PENDING:
        return jsonify({'error': 'User does not have a pending application'}), 400
    
    data = request.get_json()
    
    # Validate text fields
    business_name = data.get('businessName', f'Negocio de {user.email}')
    if business_name and not validate_text(business_name):
        return jsonify({'error': 'El nombre del negocio contiene caracteres no permitidos'}), 400
    
    address = data.get('address', '')
    if address and not validate_text(address):
        return jsonify({'error': 'La dirección contiene caracteres no permitidos'}), 400
    
    # Validate phone number
    phone = data.get('phone', '')
    if phone and not validate_phone(phone):
        return jsonify({'error': 'El teléfono solo puede contener números y los símbolos: +, -, espacios, paréntesis'}), 400
    
    hours = data.get('hours', 'Lun-Vie: 9:00-18:00')
    if hours and not validate_text(hours):
        return jsonify({'error': 'Los horarios contienen caracteres no permitidos'}), 400
    
    description = data.get('description', '')
    if description and not validate_text(description):
        return jsonify({'error': 'La descripción contiene caracteres no permitidos'}), 400
    
    # Create the business
    business_id = f"business-{uuid.uuid4().hex[:8]}"
    new_business = TireBusiness(
        id=business_id,
        nombre=business_name,
        direccion=address,
        telefono=phone,
        email=data.get('email', user.email),
        horarios=data.get('hours', 'Lun-Vie: 9:00-18:00'),
        descripcion=data.get('description', ''),
        calificacion=0.0,
        cantidad_resenas=0
    )
    
    db.session.add(new_business)
    
    # Update user
    user.estado_solicitud_negocio = BusinessApplicationStatus.APPROVED
    user.negocio_id = business_id
    user.rol = UserRole.BUSINESS_ADMIN
    
    db.session.commit()
    
    return jsonify({
        'message': 'Business application approved',
        'user': user_to_dict(user),
        'business': {
            'id': new_business.id,
            'name': new_business.nombre
        }
    }), 200

@users_bp.route('/<user_id>/reject-business', methods=['POST'])
@require_super_admin
def reject_business_application(user_id):
    """Reject a business application. Super admin only."""
    user = User.query.filter_by(id=user_id).first()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    
    if user.estado_solicitud_negocio != BusinessApplicationStatus.PENDING:
        return jsonify({'error': 'User does not have a pending application'}), 400
    
    data = request.get_json()
    rejection_reason = data.get('reason', '')
    
    user.estado_solicitud_negocio = BusinessApplicationStatus.REJECTED
    
    db.session.commit()
    
    return jsonify({
        'message': 'Business application rejected',
        'user': user_to_dict(user)
    }), 200

@users_bp.route('/<user_id>', methods=['PUT'])
@require_super_admin
def update_user(user_id):
    """Update a user. Super admin only."""
    user = User.query.filter_by(id=user_id).first()
    if not user:
        return jsonify({'error': 'User not found'}), 404
    
    data = request.get_json()
    
    if 'email' in data:
        existing = User.query.filter_by(email=data['email']).filter(User.id != user_id).first()
        if existing:
            return jsonify({'error': 'Email already in use'}), 400
        user.email = data['email']
    
    if 'role' in data:
        user.role = UserRole(data['role'])
    if 'business_id' in data:
        user.business_id = data['business_id']
    if 'business_application_status' in data:
        user.business_application_status = BusinessApplicationStatus(data['business_application_status'])
    
    db.session.commit()
    
    return jsonify(user_to_dict(user)), 200
