"""
AI Models Management Routes
Handles API endpoints for AI model configuration and selection
"""

import json
import logging
from flask import Blueprint, request, jsonify
import sys
import os

# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from utils import require_api_key, encrypt_response
from aimodel_selector.db_manager import (
    get_all_ai_models,
    get_ai_model_by_name,
    get_ai_model_by_id,
    get_ai_models_by_provider,
    get_ai_models_by_capability,
    create_ai_model,
    update_ai_model,
    delete_ai_model,
    get_provider_list,
    initialize_ai_models_table
)
from aimodel_selector.models_config import (
    get_default_model,
    get_model_config,
    get_all_models,
    get_no_auth_models,
    get_coding_models,
    get_vision_models,
    get_provider_stats,
    get_recommended_models
)

logger = logging.getLogger(__name__)

# Create blueprint
model_routes_bp = Blueprint('model_routes', __name__, url_prefix='/api/models')


def create_error_response(message, status_code=400):
    """Create standardized error response"""
    return jsonify({"status": "error", "message": message}), status_code


def format_api_response(data):
    """Format successful API response"""
    return jsonify({"status": "success", "data": data})


# ===== PUBLIC ENDPOINTS (with API key) =====

@model_routes_bp.route('/', methods=['GET'])
@require_api_key
@encrypt_response
def get_models():
    """
    Get all available AI models
    Query params:
        - active_only: boolean (default: true) - only return active models
        - provider: string - filter by provider
        - capability: string - filter by capability (text, code, vision, image)
    """
    try:
        active_only = request.args.get('active_only', 'true').lower() == 'true'
        provider = request.args.get('provider')
        capability = request.args.get('capability')
        
        if provider:
            models = get_ai_models_by_provider(provider)
        elif capability:
            models = get_ai_models_by_capability(capability)
        else:
            models = get_all_models() if active_only else get_all_ai_models(active_only=False)

        # Filter by active backend so the frontend only sees relevant models
        try:
            from services.ai_config import is_groq_enabled, is_g4f_enabled
            if is_groq_enabled():
                models = [m for m in models if m.get('backend_type') == 'groq']
            elif is_g4f_enabled():
                models = [m for m in models if m.get('backend_type') == 'g4f']
        except ImportError:
            pass

        # Remove sensitive data before sending
        safe_models = [
            {
                "id": m.get("id"),
                "name": m["name"],
                "description": m["description"],
                "tier": m["tier"],
                "provider": m["provider"],
                "status": m["status"],
                "capabilities": m["capabilities"],
                "max_tokens": m["max_tokens"],
                "auth_required": m["auth_required"]
            }
            for m in models
        ]
        
        return format_api_response({
            "models": safe_models,
            "count": len(safe_models)
        })
        
    except Exception as e:
        logger.error(f"Error fetching models: {e}")
        return create_error_response(f"Failed to fetch models: {str(e)}", 500)


@model_routes_bp.route('/default', methods=['GET'])
@require_api_key
@encrypt_response
def get_default():
    """Get the default model name"""
    try:
        user_id = request.args.get('user_id')
        default_model = get_default_model(user_id=user_id)
        model_config = get_model_config(default_model)
        
        # Remove sensitive data
        safe_config = {
            "name": model_config.get("name"),
            "model": model_config.get("model"),
            "provider": model_config.get("provider"),
            "description": model_config.get("description"),
            "capabilities": model_config.get("capabilities", []),
            "max_tokens": model_config.get("max_tokens", 8192)
        }
        
        return format_api_response(safe_config)
        
    except Exception as e:
        logger.error(f"Error fetching default model: {e}")
        return create_error_response(f"Failed to fetch default model: {str(e)}", 500)


@model_routes_bp.route('/<string:model_name>', methods=['GET'])
@require_api_key
@encrypt_response
def get_model_by_name(model_name):
    """Get a specific model by name"""
    try:
        model = get_ai_model_by_name(model_name)
        
        if not model:
            return create_error_response(f"Model '{model_name}' not found", 404)
        
        # Remove sensitive data
        safe_model = {
            "id": model.get("id"),
            "name": model["name"],
            "description": model["description"],
            "tier": model["tier"],
            "model": model["model"],
            "provider": model["provider"],
            "status": model["status"],
            "capabilities": model["capabilities"],
            "max_tokens": model["max_tokens"],
            "auth_required": model["auth_required"]
        }
        
        return format_api_response(safe_model)
        
    except Exception as e:
        logger.error(f"Error fetching model {model_name}: {e}")
        return create_error_response(f"Failed to fetch model: {str(e)}", 500)


@model_routes_bp.route('/providers', methods=['GET'])
@require_api_key
@encrypt_response
def get_providers():
    """Get list of all available providers"""
    try:
        providers = get_provider_list()
        return format_api_response({
            "providers": providers,
            "count": len(providers)
        })
        
    except Exception as e:
        logger.error(f"Error fetching providers: {e}")
        return create_error_response(f"Failed to fetch providers: {str(e)}", 500)


@model_routes_bp.route('/stats', methods=['GET'])
@require_api_key
@encrypt_response
def get_stats():
    """Get provider and model statistics"""
    try:
        stats = get_provider_stats()
        return format_api_response(stats)
        
    except Exception as e:
        logger.error(f"Error fetching stats: {e}")
        return create_error_response(f"Failed to fetch stats: {str(e)}", 500)


@model_routes_bp.route('/recommended', methods=['GET'])
@require_api_key
@encrypt_response
def get_recommended():
    """Get recommended models for different use cases"""
    try:
        recommended = get_recommended_models()
        return format_api_response(recommended)
        
    except Exception as e:
        logger.error(f"Error fetching recommended models: {e}")
        return create_error_response(f"Failed to fetch recommended models: {str(e)}", 500)


@model_routes_bp.route('/coding', methods=['GET'])
@require_api_key
@encrypt_response
def get_coding():
    """Get models optimized for coding"""
    try:
        models = get_coding_models()
        safe_models = [
            {
                "name": m["name"],
                "description": m["description"],
                "provider": m["provider"],
                "max_tokens": m["max_tokens"]
            }
            for m in models
        ]
        return format_api_response({
            "models": safe_models,
            "count": len(safe_models)
        })
        
    except Exception as e:
        logger.error(f"Error fetching coding models: {e}")
        return create_error_response(f"Failed to fetch coding models: {str(e)}", 500)


@model_routes_bp.route('/vision', methods=['GET'])
@require_api_key
@encrypt_response
def get_vision():
    """Get models with vision capabilities"""
    try:
        models = get_vision_models()
        safe_models = [
            {
                "name": m["name"],
                "description": m["description"],
                "provider": m["provider"],
                "max_tokens": m["max_tokens"]
            }
            for m in models
        ]
        return format_api_response({
            "models": safe_models,
            "count": len(safe_models)
        })
        
    except Exception as e:
        logger.error(f"Error fetching vision models: {e}")
        return create_error_response(f"Failed to fetch vision models: {str(e)}", 500)


@model_routes_bp.route('/no-auth', methods=['GET'])
@require_api_key
@encrypt_response
def get_no_auth():
    """Get models that don't require authentication"""
    try:
        models = get_no_auth_models()
        safe_models = [
            {
                "name": m["name"],
                "description": m["description"],
                "provider": m["provider"],
                "capabilities": m["capabilities"],
                "max_tokens": m["max_tokens"]
            }
            for m in models
        ]
        return format_api_response({
            "models": safe_models,
            "count": len(safe_models)
        })
        
    except Exception as e:
        logger.error(f"Error fetching no-auth models: {e}")
        return create_error_response(f"Failed to fetch no-auth models: {str(e)}", 500)


# ===== ADMIN ENDPOINTS (require admin privileges) =====

@model_routes_bp.route('/admin/create', methods=['POST'])
@require_api_key
@encrypt_response
def create_model():
    """Create a new AI model (Admin only)"""
    try:
        data = request.get_json()
        
        # Validate required fields
        required_fields = ['name', 'description', 'tier', 'model', 'provider']
        for field in required_fields:
            if field not in data:
                return create_error_response(f"Missing required field: {field}", 400)
        
        model_id = create_ai_model(
            name=data['name'],
            description=data['description'],
            tier=data['tier'],
            model=data['model'],
            provider=data['provider'],
            api_key=data.get('api_key'),
            base_url=data.get('base_url'),
            status=data.get('status', 'active'),
            capabilities=data.get('capabilities', []),
            max_tokens=data.get('max_tokens', 8192),
            auth_required=data.get('auth_required', False)
        )
        
        if model_id:
            return format_api_response({
                "message": "Model created successfully",
                "model_id": model_id
            })
        else:
            return create_error_response("Failed to create model", 500)
            
    except Exception as e:
        logger.error(f"Error creating model: {e}")
        return create_error_response(f"Failed to create model: {str(e)}", 500)


@model_routes_bp.route('/admin/update/<int:model_id>', methods=['PUT'])
@require_api_key
@encrypt_response
def update_model(model_id):
    """Update an existing AI model (Admin only)"""
    try:
        data = request.get_json()
        
        success = update_ai_model(model_id, **data)
        
        if success:
            return format_api_response({
                "message": "Model updated successfully",
                "model_id": model_id
            })
        else:
            return create_error_response("Failed to update model", 500)
            
    except Exception as e:
        logger.error(f"Error updating model: {e}")
        return create_error_response(f"Failed to update model: {str(e)}", 500)


@model_routes_bp.route('/admin/delete/<int:model_id>', methods=['DELETE'])
@require_api_key
@encrypt_response
def delete_model(model_id):
    """Delete/deactivate an AI model (Admin only)"""
    try:
        success = delete_ai_model(model_id)
        
        if success:
            return format_api_response({
                "message": "Model deleted/deactivated successfully",
                "model_id": model_id
            })
        else:
            return create_error_response("Failed to delete model", 500)
            
    except Exception as e:
        logger.error(f"Error deleting model: {e}")
        return create_error_response(f"Failed to delete model: {str(e)}", 500)


@model_routes_bp.route('/admin/initialize', methods=['POST'])
@require_api_key
@encrypt_response
def initialize_table():
    """Initialize the AI models table (Admin only)"""
    try:
        success = initialize_ai_models_table()
        
        if success:
            return format_api_response({
                "message": "AI models table initialized successfully"
            })
        else:
            return create_error_response("Failed to initialize table", 500)
            
    except Exception as e:
        logger.error(f"Error initializing table: {e}")
        return create_error_response(f"Failed to initialize table: {str(e)}", 500)


# Initialize table on module load (optional - can be removed if you prefer manual init)
try:
    initialize_ai_models_table()
    logger.info("AI models table initialized")
except Exception as e:
    logger.warning(f"Could not auto-initialize AI models table: {e}")

