from flask import Blueprint, request, jsonify
from app.database import db
from app.models import TireBusiness
from app.auth import get_current_user, require_super_admin
import re

businesses_bp = Blueprint('businesses', __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_url(url):
    """Validate URL format"""
    if not url:
        return True  # Allow empty URL (optional field)
    url_regex = r'^https?://.+'
    return bool(re.match(url_regex, url))

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 validate_number(value, allow_decimal=False):
    """Validate number - only allow positive numbers"""
    if value is None:
        return True
    try:
        num = float(value) if allow_decimal else int(value)
        return num >= 0
    except (ValueError, TypeError):
        return False

@businesses_bp.route('/health', methods=['GET'])
def health_check():
    """Health check endpoint to verify database connection."""
    try:
        count = TireBusiness.query.count()
        return jsonify({
            'status': 'healthy',
            'database_connected': True,
            'businesses_count': count
        }), 200
    except Exception as e:
        return jsonify({
            'status': 'unhealthy',
            'database_connected': False,
            'error': str(e)
        }), 500

def business_to_dict(business):
    """Convert TireBusiness model to dictionary."""
    return {
        'id': business.id,
        'name': business.name,
        'address': business.address,
        'contact': {
            'phone': business.phone,
            'email': business.email
        },
        'hours': business.hours,
        'rating': business.rating,
        'reviewCount': business.review_count,
        'description': business.description,
        'googleMapsEmbedUrl': business.google_maps_embed_url,
        'imageUrl': business.image_url,
        'socials': business.socials if business.socials else None,
        'created_at': business.created_at.isoformat() if business.created_at else None
    }

@businesses_bp.route('', methods=['GET'])
def get_businesses():
    """Get all businesses. Public endpoint."""
    try:
        skip = request.args.get('skip', 0, type=int)
        limit = request.args.get('limit', 100, type=int)
        
        businesses = TireBusiness.query.offset(skip).limit(limit).all()
        result = [business_to_dict(b) for b in businesses]
        return jsonify(result), 200
    except Exception as e:
        import traceback
        traceback.print_exc()
        return jsonify({'error': f'Error al obtener negocios: {str(e)}'}), 500

@businesses_bp.route('/<business_id>', methods=['GET'])
def get_business(business_id):
    """Get a specific business by ID. Public endpoint."""
    business = TireBusiness.query.filter_by(id=business_id).first()
    if not business:
        return jsonify({'error': 'Business not found'}), 404
    return jsonify(business_to_dict(business)), 200

@businesses_bp.route('', methods=['POST'])
def create_business():
    """Create a new business. Authenticated users only."""
    from flask_jwt_extended import jwt_required
    jwt_required()
    
    user = get_current_user()
    if not user:
        return jsonify({'error': 'Authentication required'}), 401
    
    data = request.get_json()
    
    business_id = data.get('id')
    if business_id:
        existing = TireBusiness.query.filter_by(id=business_id).first()
        if existing:
            return jsonify({'error': 'Business ID already exists'}), 400
    
    # Validate text fields
    name = data.get('name', '')
    if name and not validate_text(name):
        return jsonify({'error': 'El nombre 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
    
    contact = data.get('contact', {})
    socials = data.get('socials')
    
    # Validate phone number
    phone = contact.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
    
    # Validate URLs
    image_url = data.get('imageUrl', '')
    if image_url and not validate_url(image_url):
        return jsonify({'error': 'La URL de imagen debe comenzar con http:// o https://'}), 400
    
    google_maps_url = data.get('googleMapsEmbedUrl', '')
    if google_maps_url and not validate_url(google_maps_url):
        return jsonify({'error': 'La URL de Google Maps debe comenzar con http:// o https://'}), 400
    
    # Validate social media URLs
    if socials:
        for platform, url in socials.items():
            if url and not validate_url(url):
                return jsonify({'error': f'La URL de {platform} debe comenzar con http:// o https://'}), 400
    
    new_business = TireBusiness(
        id=business_id or f"biz-{data.get('name', '').lower().replace(' ', '-')}",
        name=data.get('name'),
        address=data.get('address'),
        phone=phone,
        email=contact.get('email'),
        hours=data.get('hours'),
        description=data.get('description'),
        google_maps_embed_url=data.get('googleMapsEmbedUrl'),
        image_url=data.get('imageUrl'),
        socials=socials
    )
    
    db.session.add(new_business)
    db.session.commit()
    
    return jsonify(business_to_dict(new_business)), 201

@businesses_bp.route('/<business_id>', methods=['PUT'])
def update_business(business_id):
    """Update a business. Business admin or super admin only."""
    from flask_jwt_extended import jwt_required
    jwt_required()
    
    user = get_current_user()
    if not user:
        return jsonify({'error': 'Authentication required'}), 401
    
    # Check permissions
    if user.role.value != 'super-admin':
        if user.role.value != 'business-admin' or user.business_id != business_id:
            return jsonify({'error': 'You can only update your own business'}), 403
    
    business = TireBusiness.query.filter_by(id=business_id).first()
    if not business:
        return jsonify({'error': 'Business not found'}), 404
    
    data = request.get_json()
    
    if 'name' in data:
        name = data['name']
        if name and not validate_text(name):
            return jsonify({'error': 'El nombre contiene caracteres no permitidos'}), 400
        business.name = name
    if 'address' in data:
        address = data['address']
        if address and not validate_text(address):
            return jsonify({'error': 'La dirección contiene caracteres no permitidos'}), 400
        business.address = address
    if 'contact' in data:
        contact = data['contact']
        phone = contact.get('phone', business.phone)
        # Validate phone number
        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
        business.phone = phone
        business.email = contact.get('email', business.email)
    if 'imageUrl' in data:
        image_url = data['imageUrl']
        if image_url and not validate_url(image_url):
            return jsonify({'error': 'La URL de imagen debe comenzar con http:// o https://'}), 400
        business.image_url = image_url
    if 'googleMapsEmbedUrl' in data:
        google_maps_url = data['googleMapsEmbedUrl']
        if google_maps_url and not validate_url(google_maps_url):
            return jsonify({'error': 'La URL de Google Maps debe comenzar con http:// o https://'}), 400
        business.google_maps_embed_url = google_maps_url
    if 'socials' in data:
        socials = data['socials']
        for platform, url in (socials or {}).items():
            if url and not validate_url(url):
                return jsonify({'error': f'La URL de {platform} debe comenzar con http:// o https://'}), 400
        business.socials = socials
    if 'hours' in data:
        business.hours = data['hours']
    if 'description' in data:
        business.description = data['description']
    if 'googleMapsEmbedUrl' in data:
        business.google_maps_embed_url = data['googleMapsEmbedUrl']
    if 'imageUrl' in data:
        business.image_url = data['imageUrl']
    if 'socials' in data:
        business.socials = data['socials']
    
    db.session.commit()
    
    return jsonify(business_to_dict(business)), 200

@businesses_bp.route('/<business_id>', methods=['DELETE'])
@require_super_admin
def delete_business(business_id):
    """Delete a business. Super admin only."""
    business = TireBusiness.query.filter_by(id=business_id).first()
    if not business:
        return jsonify({'error': 'Business not found'}), 404
    
    db.session.delete(business)
    db.session.commit()
    
    return '', 204
