from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, verify_jwt_in_request
from app.database import db
from app.models import InventoryItem
from app.auth import get_current_user

inventory_bp = Blueprint('inventory', __name__)

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

def inventory_to_dict(item):
    """Convert InventoryItem model to dictionary."""
    return {
        'id': item.id,
        'business_id': item.negocio_id,
        'tire_id': item.llanta_id,
        'quantity': item.cantidad,
        'price': item.precio,
        'created_at': item.creado_en.isoformat() if item.creado_en else None
    }

@inventory_bp.route('', methods=['GET'])
def get_inventory():
    """Get inventory items. Public when filtering by tire_id or no filters, requires auth for business_id filter."""
    try:
        business_id = request.args.get('business_id')
        tire_id = request.args.get('tire_id')
        skip = request.args.get('skip', 0, type=int)
        limit = request.args.get('limit', 100, type=int)
        
        query = InventoryItem.query
        
        # If filtering by tire_id, it's a public endpoint (for price comparison)
        if tire_id:
            query = query.filter(InventoryItem.llanta_id == tire_id)
            # Only show items with quantity > 0 for public access
            query = query.filter(InventoryItem.cantidad > 0)
            items = query.offset(skip).limit(limit).all()
            return jsonify([inventory_to_dict(item) for item in items]), 200
        
        # If no filters, return all public inventory (for catalog browsing)
        # Only show items with quantity > 0 for public access
        if not business_id:
            query = query.filter(InventoryItem.cantidad > 0)
            items = query.offset(skip).limit(limit).all()
            return jsonify([inventory_to_dict(item) for item in items]), 200
        
        # For business_id filter, require authentication
        try:
            verify_jwt_in_request()
            user = get_current_user()
            if not user:
                return jsonify({'error': 'Authentication required'}), 401
            
            # Business admins can only see their own business inventory
            if user.role.value == 'business-admin':
                if user.business_id:
                    query = query.filter(InventoryItem.negocio_id == user.business_id)
                else:
                    return jsonify([]), 200
            else:
                query = query.filter(InventoryItem.negocio_id == business_id)
            
            items = query.offset(skip).limit(limit).all()
            return jsonify([inventory_to_dict(item) for item in items]), 200
        except:
            return jsonify({'error': 'Authentication required for this query'}), 401
    except Exception as e:
        import traceback
        error_msg = traceback.format_exc()
        print(f"Error in get_inventory: {error_msg}")
        return jsonify({'error': str(e), 'details': error_msg}), 500

@inventory_bp.route('/business/<business_id>', methods=['GET'])
def get_business_inventory(business_id):
    """Get inventory for a specific business. Public endpoint for viewing."""
    try:
        # Explicitly filter by business_id and ensure quantity > 0
        # Using filter() instead of filter_by() for explicit column reference
        items = InventoryItem.query.filter(
            InventoryItem.negocio_id == business_id,
            InventoryItem.cantidad > 0
        ).all()
        
        # Double-check: ensure all items belong to the requested business
        valid_items = [item for item in items if item.negocio_id == business_id and item.cantidad > 0]
        
        return jsonify([inventory_to_dict(item) for item in valid_items]), 200
    except Exception as e:
        import traceback
        error_msg = traceback.format_exc()
        print(f"Error in get_business_inventory: {error_msg}")
        return jsonify({'error': str(e), 'details': error_msg}), 500

@inventory_bp.route('/<inventory_id>', methods=['GET'])
def get_inventory_item(inventory_id):
    """Get a specific inventory item. Public endpoint."""
    item = InventoryItem.query.filter_by(id=inventory_id).first()
    if not item:
        return jsonify({'error': 'Inventory item not found'}), 404
    
    # Only show if quantity > 0 for public access
    if item.cantidad <= 0:
        return jsonify({'error': 'Inventory item not available'}), 404
    
    return jsonify(inventory_to_dict(item)), 200

@inventory_bp.route('', methods=['POST'])
@jwt_required()
def create_inventory_item():
    """Create an inventory item. Business admin or super admin only."""
    user = get_current_user()
    if not user:
        return jsonify({'error': 'Authentication required'}), 401
    
    data = request.get_json()
    business_id = data.get('business_id')
    tire_id = data.get('tire_id')
    quantity = data.get('quantity', 0)
    price = data.get('price')
    
    if not all([business_id, tire_id, price]):
        return jsonify({'error': 'Missing required fields'}), 400
    
    # Validate numbers
    if quantity is not None and not validate_number(quantity):
        return jsonify({'error': 'La cantidad debe ser un número positivo o cero'}), 400
    if price is not None and not validate_number(price, allow_decimal=True):
        return jsonify({'error': 'El precio debe ser un número positivo o cero'}), 400
    
    # Check permissions
    if user.role.value == 'business-admin':
        if user.business_id != business_id:
            return jsonify({'error': 'You can only add inventory to your own business'}), 403
    
    # Check if item already exists
    existing = InventoryItem.query.filter_by(
        negocio_id=business_id,
        llanta_id=tire_id
    ).first()
    
    if existing:
        return jsonify({'error': 'Inventory item already exists for this business and tire'}), 400
    
    new_item = InventoryItem(
        id=f"inv-{business_id}-{tire_id}",
        business_id=business_id,
        tire_id=tire_id,
        quantity=quantity,
        price=price
    )
    
    db.session.add(new_item)
    db.session.commit()
    
    return jsonify(inventory_to_dict(new_item)), 201

@inventory_bp.route('/<inventory_id>', methods=['PUT'])
@jwt_required()
def update_inventory_item(inventory_id):
    """Update an inventory item. Business admin or super admin only."""
    user = get_current_user()
    if not user:
        return jsonify({'error': 'Authentication required'}), 401
    
    item = InventoryItem.query.filter_by(id=inventory_id).first()
    if not item:
        return jsonify({'error': 'Inventory item not found'}), 404
    
    # Check permissions
    if user.role.value == 'business-admin':
        if user.business_id != item.negocio_id:
            return jsonify({'error': 'You can only update inventory for your own business'}), 403
    
    data = request.get_json()
    
    if 'quantity' in data:
        quantity = data['quantity']
        if quantity is not None and not validate_number(quantity):
            return jsonify({'error': 'La cantidad debe ser un número positivo o cero'}), 400
        item.quantity = quantity
    if 'price' in data:
        price = data['price']
        if price is not None and not validate_number(price, allow_decimal=True):
            return jsonify({'error': 'El precio debe ser un número positivo o cero'}), 400
        item.price = price
    
    db.session.commit()
    
    return jsonify(inventory_to_dict(item)), 200

@inventory_bp.route('/<inventory_id>', methods=['DELETE'])
@jwt_required()
def delete_inventory_item(inventory_id):
    """Delete an inventory item. Business admin or super admin only."""
    user = get_current_user()
    if not user:
        return jsonify({'error': 'Authentication required'}), 401
    
    item = InventoryItem.query.filter_by(id=inventory_id).first()
    if not item:
        return jsonify({'error': 'Inventory item not found'}), 404
    
    # Check permissions
    if user.role.value == 'business-admin':
        if user.business_id != item.negocio_id:
            return jsonify({'error': 'You can only delete inventory for your own business'}), 403
    
    db.session.delete(item)
    db.session.commit()
    
    return '', 204
