"""
Flask routes for web dashboard
"""

import logging
from datetime import datetime
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash, session
from flask_login import login_required, current_user, login_user, logout_user
from werkzeug.security import check_password_hash
from werkzeug.utils import secure_filename

from .auth import AuthenticatedUser
from ..core.message_bus import Message, MessageType

logger = logging.getLogger(__name__)

# Blueprint definitions
main_bp = Blueprint('main', __name__)
auth_bp = Blueprint('auth', __name__)
api_bp = Blueprint('api', __name__)

# These will be set by the app.py when registering blueprints
main_bp.db_manager = None
main_bp.config_manager = None  
main_bp.message_bus = None

auth_bp.auth_manager = None
auth_bp.db_manager = None

api_bp.api = None
api_bp.db_manager = None
api_bp.config_manager = None
api_bp.message_bus = None


# Main routes
@main_bp.route('/')
@login_required
def index():
    """Dashboard home page - redirects cashier users to cashier dashboard"""
    try:
        # Check if user is cashier and redirect them to cashier dashboard
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/index.html',
                             user=current_user,
                             page_title="Dashboard")
    except Exception as e:
        logger.error(f"Dashboard index error: {e}")
        flash("Error loading dashboard", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/cashier')
@login_required
def cashier_dashboard():
    """Cashier-specific dashboard page"""
    try:
        # Verify user is cashier
        if not (hasattr(current_user, 'role') and current_user.role == 'cashier'):
            if not (hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user()):
                flash("Cashier access required", "error")
                return redirect(url_for('main.index'))
        
        return render_template('dashboard/cashier.html',
                             user=current_user,
                             page_title="Cashier Dashboard")
    except Exception as e:
        logger.error(f"Cashier dashboard error: {e}")
        flash("Error loading cashier dashboard", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/video')
@login_required
def video_control_page():
    """Video control page"""
    try:
        return render_template('dashboard/video.html',
                             user=current_user,
                             page_title="Video Control")
    except Exception as e:
        logger.error(f"Video control page error: {e}")
        flash("Error loading video control", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/templates')
@login_required
def templates():
    """Template management page"""
    try:
        # Restrict cashier users from accessing templates page
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/templates.html',
                             user=current_user,
                             page_title="Templates")
    except Exception as e:
        logger.error(f"Templates page error: {e}")
        flash("Error loading templates", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/config')
@login_required
def configuration():
    """Configuration page"""
    try:
        if not current_user.is_admin:
            flash("Admin access required", "error")
            # Redirect cashier users to their dashboard
            if hasattr(current_user, 'role') and current_user.role == 'cashier':
                return redirect(url_for('main.cashier_dashboard'))
            elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
                return redirect(url_for('main.cashier_dashboard'))
            return redirect(url_for('main.index'))
        
        # Get current configuration values
        config_data = {}
        try:
            if main_bp.config_manager:
                # Load configuration values from database/config manager
                general_config = main_bp.config_manager.get_section_config("general") or {}
                video_config = main_bp.config_manager.get_section_config("video") or {}
                database_config = main_bp.config_manager.get_section_config("database") or {}
                api_config = main_bp.config_manager.get_section_config("api") or {}
                
                config_data.update({
                    # General settings
                    'app_name': general_config.get('app_name', 'MbetterClient'),
                    'log_level': general_config.get('log_level', 'INFO'),
                    'enable_qt': general_config.get('enable_qt', True),
                    
                    # Video settings
                    'video_width': video_config.get('video_width', 1920),
                    'video_height': video_config.get('video_height', 1080),
                    'fullscreen': video_config.get('fullscreen', False),
                    
                    # Database settings
                    'db_path': database_config.get('db_path', 'data/mbetterclient.db'),
                    
                    # API settings
                    'fastapi_url': api_config.get('fastapi_url', 'https://mbetter.nexlab.net/api/updates'),
                    'api_token': api_config.get('api_token', ''),
                    'api_interval': api_config.get('api_interval', 1800),
                    'api_timeout': api_config.get('api_timeout', 30),
                    'api_enabled': api_config.get('api_enabled', True)
                })
        except Exception as e:
            logger.warning(f"Error loading configuration values: {e}")
            # Use defaults if config loading fails
            config_data = {
                'app_name': 'MbetterClient',
                'log_level': 'INFO',
                'enable_qt': True,
                'video_width': 1920,
                'video_height': 1080,
                'fullscreen': False,
                'db_path': 'data/mbetterclient.db',
                'fastapi_url': 'https://mbetter.nexlab.net/api/updates',
                'api_token': '',
                'api_interval': 1800,
                'api_timeout': 30,
                'api_enabled': True
            }
        
        return render_template('dashboard/config.html',
                             user=current_user,
                             config=config_data,
                             page_title="Configuration")
    except Exception as e:
        logger.error(f"Configuration page error: {e}")
        flash("Error loading configuration", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/users')
@login_required
def users():
    """User management page"""
    try:
        if not current_user.is_admin:
            flash("Admin access required", "error")
            # Redirect cashier users to their dashboard
            if hasattr(current_user, 'role') and current_user.role == 'cashier':
                return redirect(url_for('main.cashier_dashboard'))
            elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
                return redirect(url_for('main.cashier_dashboard'))
            return redirect(url_for('main.index'))
        
        return render_template('dashboard/users.html',
                             user=current_user,
                             page_title="User Management")
    except Exception as e:
        logger.error(f"Users page error: {e}")
        flash("Error loading user management", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/tokens')
@login_required
def api_tokens():
    """API token management page"""
    try:
        # Restrict cashier users from accessing API tokens page
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/tokens.html',
                             user=current_user,
                             page_title="API Tokens")
    except Exception as e:
        logger.error(f"API tokens page error: {e}")
        flash("Error loading API tokens", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/fixtures')
@login_required
def fixtures():
    """Fixtures management page"""
    try:
        # Restrict cashier users from accessing fixtures page
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/fixtures.html',
                             user=current_user,
                             page_title="Fixtures")
    except Exception as e:
        logger.error(f"Fixtures page error: {e}")
        flash("Error loading fixtures", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/fixtures/<int:match_id>')
@login_required
def fixture_details(match_id):
    """Fixture details page showing match and outcomes"""
    try:
        # Restrict cashier users from accessing fixture details page
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/fixture_details.html',
                             user=current_user,
                             match_id=match_id,
                             page_title=f"Fixture Details - Match #{match_id}")
    except Exception as e:
        logger.error(f"Fixture details page error: {e}")
        flash("Error loading fixture details", "error")
        return render_template('errors/500.html'), 500


@main_bp.route('/logs')
@login_required
def logs():
    """Application logs page"""
    try:
        if not current_user.is_admin:
            flash("Admin access required", "error")
            # Redirect cashier users to their dashboard
            if hasattr(current_user, 'role') and current_user.role == 'cashier':
                return redirect(url_for('main.cashier_dashboard'))
            elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
                return redirect(url_for('main.cashier_dashboard'))
            return redirect(url_for('main.index'))
        
        return render_template('dashboard/logs.html',
                             user=current_user,
                             page_title="Application Logs")
    except Exception as e:
        logger.error(f"Logs page error: {e}")
        flash("Error loading logs", "error")
        return render_template('errors/500.html'), 500


# Auth routes
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    """Login page"""
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    
    if request.method == 'POST':
        try:
            username = request.form.get('username', '').strip()
            password = request.form.get('password', '')
            remember_me = request.form.get('remember_me', False)
            
            if not username or not password:
                flash("Username and password are required", "error")
                return render_template('auth/login.html')
            
            # Authenticate user
            authenticated_user = auth_bp.auth_manager.authenticate_user(username, password)
            
            if authenticated_user:
                login_user(authenticated_user, remember=remember_me)
                logger.info(f"User logged in: {username}")
                
                # Redirect to next page or appropriate dashboard
                next_page = request.args.get('next')
                if next_page:
                    return redirect(next_page)
                else:
                    # Redirect cashier users to their specific dashboard
                    if hasattr(authenticated_user, 'role') and authenticated_user.role == 'cashier':
                        return redirect(url_for('main.cashier_dashboard'))
                    elif hasattr(authenticated_user, 'is_cashier_user') and authenticated_user.is_cashier_user():
                        return redirect(url_for('main.cashier_dashboard'))
                    else:
                        return redirect(url_for('main.index'))
            else:
                flash("Invalid username or password", "error")
                return render_template('auth/login.html')
                
        except Exception as e:
            logger.error(f"Login error: {e}")
            flash("Login failed. Please try again.", "error")
            return render_template('auth/login.html')
    
    return render_template('auth/login.html')
    
    
@main_bp.route('/video_test')
@login_required
def video_test():
    """Video upload test page"""
    try:
        # Restrict cashier users from accessing video test page
        if hasattr(current_user, 'role') and current_user.role == 'cashier':
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        elif hasattr(current_user, 'is_cashier_user') and current_user.is_cashier_user():
            flash("Access denied", "error")
            return redirect(url_for('main.cashier_dashboard'))
        
        return render_template('dashboard/video_test.html',
                             user=current_user,
                             page_title="Video Upload Test")
    except Exception as e:
        logger.error(f"Video test page error: {e}")
        flash("Error loading video test page", "error")
        return render_template('errors/500.html'), 500


@auth_bp.route('/logout')
@login_required
def logout():
    """Logout user"""
    try:
        username = current_user.username
        logout_user()
        logger.info(f"User logged out: {username}")
        flash("You have been logged out", "info")
    except Exception as e:
        logger.error(f"Logout error: {e}")
    
    return redirect(url_for('auth.login'))


@auth_bp.route('/change-password', methods=['GET', 'POST'])
@login_required
def change_password():
    """Change password page"""
    if request.method == 'POST':
        try:
            current_password = request.form.get('current_password', '')
            new_password = request.form.get('new_password', '')
            confirm_password = request.form.get('confirm_password', '')
            
            if not all([current_password, new_password, confirm_password]):
                flash("All fields are required", "error")
                return render_template('auth/change_password.html')
            
            if new_password != confirm_password:
                flash("New passwords do not match", "error")
                return render_template('auth/change_password.html')
            
            if len(new_password) < 6:
                flash("Password must be at least 6 characters", "error")
                return render_template('auth/change_password.html')
            
            # Change password
            success = auth_bp.auth_manager.change_password(
                current_user.id, current_password, new_password
            )
            
            if success:
                flash("Password changed successfully", "success")
                return redirect(url_for('main.index'))
            else:
                flash("Current password is incorrect", "error")
                return render_template('auth/change_password.html')
                
        except Exception as e:
            logger.error(f"Change password error: {e}")
            flash("Failed to change password", "error")
            return render_template('auth/change_password.html')
    
    return render_template('auth/change_password.html')


# API routes
@api_bp.route('/status')
def system_status():
    """Get system status"""
    try:
        status = api_bp.api.get_system_status()
        return jsonify(status)
    except Exception as e:
        logger.error(f"API status error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/video/status')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def video_status():
    """Get video player status"""
    try:
        status = api_bp.api.get_video_status()
        return jsonify(status)
    except Exception as e:
        logger.error(f"API video status error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/video/control', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def video_control():
    """Control video player"""
    try:
        data = request.get_json() or {}
        action = data.get('action')
        
        if not action:
            return jsonify({"error": "Action is required"}), 400
        
        # Remove action from data to avoid duplicate argument error
        control_data = {k: v for k, v in data.items() if k != 'action'}
        result = api_bp.api.control_video(action, **control_data)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API video control error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/overlay', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def update_overlay():
    """Update video overlay"""
    try:
        data = request.get_json() or {}
        template = data.get('template')
        overlay_data = data.get('data', {})
        
        if not template:
            return jsonify({"error": "Template is required"}), 400
        
        result = api_bp.api.update_overlay(template, overlay_data)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API overlay update error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/templates')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_templates():
    """Get available templates"""
    try:
        templates = api_bp.api.get_templates()
        return jsonify(templates)
    except Exception as e:
        logger.error(f"API get templates error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/config')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_configuration():
    """Get configuration"""
    try:
        section = request.args.get('section')
        config = api_bp.api.get_configuration(section)
        return jsonify(config)
    except Exception as e:
        logger.error(f"API get configuration error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/config/<section>')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_config_section(section):
    """Get configuration section"""
    try:
        config = api_bp.api.get_configuration(section)
        return jsonify(config)
    except Exception as e:
        logger.error(f"API get config section error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/config/<section>', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def update_config_section(section):
    """Update configuration section"""
    try:
        data = request.get_json() or {}
        result = api_bp.api.update_configuration(section, data)
        
        # If updating API configuration, notify API client to reload
        if section == "api" and result.get("success", False):
            try:
                from ..core.message_bus import MessageBuilder, MessageType
                if api_bp.message_bus:
                    config_update_message = MessageBuilder.config_update(
                        sender="web_dashboard",
                        config_section="api",
                        config_data=data
                    )
                    api_bp.message_bus.publish(config_update_message)
                    logger.info("API configuration update message sent to message bus")
            except Exception as msg_e:
                logger.warning(f"Failed to send config update message: {msg_e}")
        
        return jsonify(result)
    except Exception as e:
        logger.error(f"API update config section error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/config', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def update_configuration():
    """Update configuration"""
    try:
        data = request.get_json() or {}
        section = data.get('section')
        config_data = data.get('config')
        
        if not section or not config_data:
            return jsonify({"error": "Section and config data are required"}), 400
        
        result = api_bp.api.update_configuration(section, config_data)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API update configuration error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/config/test-connection', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def test_api_connection():
    """Test connection to FastAPI server using request data or configured values"""
    try:
        data = request.get_json() or {}
        
        # Get URL and token from request first, fallback to configuration
        url = data.get('url', '').strip()
        token = data.get('token', '').strip()
        
        # If no URL/token in request, load from configuration
        if not url or not token:
            try:
                if api_bp.config_manager:
                    api_config = api_bp.config_manager.get_section_config("api") or {}
                    if not url:
                        url = api_config.get('fastapi_url', '').strip()
                    if not token:
                        token = api_config.get('api_token', '').strip()
                else:
                    # Fallback to default values if config manager not available
                    if not url:
                        url = 'https://mbetter.nexlab.net/api/updates'
            except Exception as e:
                logger.warning(f"Failed to load API configuration for test: {e}")
                # Fallback to default values
                if not url:
                    url = 'https://mbetter.nexlab.net/api/updates'
        
        if not url:
            return jsonify({"error": "URL is required"}), 400
        
        # Test the connection
        import requests
        from urllib.parse import urljoin
        
        # Normalize URL
        if not url.startswith(('http://', 'https://')):
            url = 'https://' + url
        
        # Call the exact configured URL without any modifications
        session = requests.Session()
        session.timeout = 10
        
        # Prepare request data
        request_data = {}
        if token:
            # Add authentication in header and request body
            session.headers.update({
                'Authorization': f'Bearer {token}'
            })
            request_data['token'] = token
        
        try:
            # Call the exact URL as configured with POST request
            response = session.post(url, json=request_data, timeout=10)
            
            auth_status = "with authentication" if token else "without authentication"
            return jsonify({
                "success": True,
                "message": f"Connection successful {auth_status}! Server responded with status {response.status_code}",
                "url": url,
                "status_code": response.status_code,
                "authenticated": bool(token)
            })
                
        except Exception as e:
            auth_info = " (with authentication)" if token else " (without authentication)"
            return jsonify({
                "success": False,
                "error": f"Connection failed{auth_info}. Error: {str(e)}"
            }), 400
        
    except Exception as e:
        logger.error(f"API connection test error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/users')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_users():
    """Get all users"""
    try:
        users = api_bp.api.get_users()
        return jsonify(users)
    except Exception as e:
        logger.error(f"API get users error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/users', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def create_user():
    """Create new user"""
    try:
        data = request.get_json() or {}
        username = data.get('username', '').strip()
        email = data.get('email', '').strip()
        password = data.get('password', '')
        is_admin = data.get('is_admin', False)
        role = data.get('role', 'normal')
        
        if not all([username, email, password]):
            return jsonify({"error": "Username, email, and password are required"}), 400
        
        # Validate role
        if role not in ['admin', 'normal', 'cashier']:
            return jsonify({"error": "Invalid role. Must be admin, normal, or cashier"}), 400
        
        result = api_bp.api.create_user(username, email, password, is_admin, role)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API create user error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/users/<int:user_id>', methods=['PUT'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def update_user(user_id):
    """Update user"""
    try:
        data = request.get_json() or {}
        username = data.get('username')
        email = data.get('email')
        password = data.get('password')
        is_admin = data.get('is_admin')
        role = data.get('role')
        
        # Validate role if provided
        if role and role not in ['admin', 'normal', 'cashier']:
            return jsonify({"error": "Invalid role. Must be admin, normal, or cashier"}), 400
        
        result = api_bp.api.update_user(user_id, username, email, password, is_admin, role)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API update user error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/users/<int:user_id>', methods=['DELETE'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def delete_user(user_id):
    """Delete user"""
    try:
        result = api_bp.api.delete_user(user_id)
        return jsonify(result)
    except Exception as e:
        logger.error(f"API delete user error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/tokens')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_api_tokens():
    """Get API tokens for current user"""
    try:
        user_id = getattr(current_user, 'id', None) or getattr(request, 'current_user', {}).get('user_id')
        
        if not user_id:
            return jsonify({"error": "User not authenticated"}), 401
        
        tokens = api_bp.api.get_api_tokens(user_id)
        return jsonify(tokens)
        
    except Exception as e:
        logger.error(f"API get tokens error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/tokens', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def create_api_token():
    """Create API token"""
    try:
        data = request.get_json() or {}
        token_name = data.get('name', '').strip()
        expires_hours = data.get('expires_hours', 8760)  # 1 year default
        
        if not token_name:
            return jsonify({"error": "Token name is required"}), 400
        
        user_id = getattr(current_user, 'id', None) or getattr(request, 'current_user', {}).get('user_id')
        
        if not user_id:
            return jsonify({"error": "User not authenticated"}), 401
        
        result = api_bp.api.create_api_token(user_id, token_name, expires_hours)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API create token error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/tokens/<int:token_id>', methods=['DELETE'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def revoke_api_token(token_id):
    """Revoke API token"""
    try:
        user_id = getattr(current_user, 'id', None) or getattr(request, 'current_user', {}).get('user_id')
        
        if not user_id:
            return jsonify({"error": "User not authenticated"}), 401
        
        result = api_bp.api.revoke_api_token(user_id, token_id)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API revoke token error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/logs')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_logs():
    """Get application logs"""
    try:
        level = request.args.get('level', 'INFO')
        limit = int(request.args.get('limit', 100))
        
        logs = api_bp.api.get_logs(level, limit)
        return jsonify(logs)
        
    except Exception as e:
        logger.error(f"API get logs error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/test-message', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def send_test_message():
    """Send test message to component"""
    try:
        data = request.get_json() or {}
        recipient = data.get('recipient')
        message_type = data.get('message_type')
        message_data = data.get('data', {})
        
        if not recipient or not message_type:
            return jsonify({"error": "Recipient and message type are required"}), 400
        
        result = api_bp.api.send_test_message(recipient, message_type, message_data)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API test message error: {e}")
        return jsonify({"error": str(e)}), 500


# Video upload and delete routes
@api_bp.route('/video/upload', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def upload_video():
    """Upload video file"""
    try:
        if 'video' not in request.files:
            return jsonify({"error": "No video file provided"}), 400
        
        file = request.files['video']
        if file.filename == '':
            return jsonify({"error": "No file selected"}), 400
        
        template = request.form.get('template', 'news_template')
        
        result = api_bp.api.upload_video(file, template)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API video upload error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/video/delete', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def delete_video():
    """Delete uploaded video"""
    try:
        data = request.get_json() or {}
        filename = data.get('filename')
        
        if not filename:
            return jsonify({"error": "Filename is required"}), 400
        
        result = api_bp.api.delete_video(filename)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"API video delete error: {e}")
        return jsonify({"error": str(e)}), 500


# Auth token endpoint for JWT creation
@auth_bp.route('/token', methods=['POST'])
def create_auth_token():
    """Create JWT authentication token"""
    try:
        data = request.get_json() or {}
        username = data.get('username', '').strip()
        password = data.get('password', '')
        
        if not username or not password:
            return jsonify({"error": "Username and password are required"}), 400
        
        # Authenticate user
        authenticated_user = auth_bp.auth_manager.authenticate_user(username, password)
        
        if authenticated_user:
            # Create JWT token
            token = auth_bp.auth_manager.create_jwt_token(authenticated_user.id)
            
            if token:
                return jsonify({
                    "access_token": token,
                    "token_type": "bearer",
                    "user": authenticated_user.to_dict()
                })
            else:
                return jsonify({"error": "Failed to create token"}), 500
        else:
            return jsonify({"error": "Invalid credentials"}), 401
            
    except Exception as e:
        logger.error(f"Token creation error: {e}")
        return jsonify({"error": str(e)}), 500
@api_bp.route('/system/shutdown', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def shutdown_application():
    """Shutdown the application (admin only)"""
    try:
        logger.info(f"Application shutdown requested by admin user")
        
        # Return success response immediately
        response = jsonify({"success": True, "message": "Shutdown initiated"})
        
        # Schedule immediate force exit in a separate thread to avoid circular dependencies
        import threading
        import time
        import os
        
        def force_shutdown():
            time.sleep(0.5)  # Give time for HTTP response to be sent
            logger.info("Web dashboard initiated force shutdown - terminating application")
            os._exit(0)
        
        shutdown_thread = threading.Thread(target=force_shutdown, daemon=True)
        shutdown_thread.start()
        
        return response
        
    except Exception as e:
        logger.error(f"API shutdown error: {e}")
        return jsonify({"error": str(e)}), 500
    
@api_bp.route('/templates/upload', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def upload_template():
    """Upload template file"""
    try:
        if 'template' not in request.files:
            return jsonify({"error": "No template file provided"}), 400
        
        file = request.files['template']
        if file.filename == '':
            return jsonify({"error": "No file selected"}), 400
        
        # Get template name from form or use filename
        template_name = request.form.get('template_name', '')
        
        result = api_bp.api.upload_template(file, template_name)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Template upload error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/templates/<template_name>', methods=['GET'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_template_content(template_name):
    """Get template content for preview"""
    try:
        from pathlib import Path
        
        # Add .html extension if not present
        if not template_name.endswith('.html'):
            template_name += '.html'
        
        # Get persistent uploaded templates directory
        uploaded_templates_dir = api_bp.api._get_persistent_templates_dir()
        
        # Get built-in templates directory
        builtin_templates_dir = Path(__file__).parent.parent / "qt_player" / "templates"
        
        # First try uploaded templates (user uploads take priority)
        template_path = uploaded_templates_dir / template_name
        
        # If not found in uploaded, try built-in templates
        if not template_path.exists():
            template_path = builtin_templates_dir / template_name
        
        if template_path.exists():
            with open(template_path, 'r', encoding='utf-8') as f:
                content = f.read()
            return content, 200, {'Content-Type': 'text/html'}
        else:
            return jsonify({"error": "Template not found"}), 404
            
    except Exception as e:
        logger.error(f"Template content fetch error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/templates/<template_name>', methods=['DELETE'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def delete_template(template_name):
    """Delete uploaded template"""
    try:
        result = api_bp.api.delete_template(template_name)
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"Template deletion error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/fixtures')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_fixtures():
    """Get all fixtures/matches"""
    try:
        from ..database.models import MatchModel
        
        session = api_bp.db_manager.get_session()
        try:
            matches = session.query(MatchModel).order_by(MatchModel.created_at.desc()).all()
            fixtures_data = []
            
            for match in matches:
                match_data = match.to_dict()
                fixtures_data.append(match_data)
            
            return jsonify({
                "success": True,
                "fixtures": fixtures_data,
                "total": len(fixtures_data)
            })
            
        finally:
            session.close()
            
    except Exception as e:
        logger.error(f"API get fixtures error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/fixtures/<int:match_id>')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_fixture_details(match_id):
    """Get fixture details by match ID"""
    try:
        from ..database.models import MatchModel, MatchOutcomeModel
        
        session = api_bp.db_manager.get_session()
        try:
            match = session.query(MatchModel).filter_by(id=match_id).first()
            
            if not match:
                return jsonify({"error": "Match not found"}), 404
            
            match_data = match.to_dict()
            
            # Get outcomes
            outcomes = session.query(MatchOutcomeModel).filter_by(match_id=match_id).all()
            match_data['outcomes'] = [outcome.to_dict() for outcome in outcomes]
            
            return jsonify({
                "success": True,
                "match": match_data
            })
            
        finally:
            session.close()
            
    except Exception as e:
        logger.error(f"API get fixture details error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/fixtures/reset', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def reset_fixtures():
    """Reset all fixtures data (admin only) - clear matches, match_outcomes, and ZIP files"""
    try:
        from ..database.models import MatchModel, MatchOutcomeModel
        from ..config.settings import get_user_data_dir
        from pathlib import Path
        import shutil
        
        session = api_bp.db_manager.get_session()
        try:
            # Count existing data before reset
            matches_count = session.query(MatchModel).count()
            outcomes_count = session.query(MatchOutcomeModel).count()
            
            # Clear all match outcomes first (due to foreign key constraints)
            session.query(MatchOutcomeModel).delete()
            session.commit()
            
            # Clear all matches
            session.query(MatchModel).delete()
            session.commit()
            
            # Clear ZIP files from persistent storage
            zip_storage_dir = Path(get_user_data_dir()) / "zip_files"
            zip_files_removed = 0
            
            if zip_storage_dir.exists():
                zip_files = list(zip_storage_dir.glob("*.zip"))
                zip_files_removed = len(zip_files)
                
                # Remove all ZIP files
                for zip_file in zip_files:
                    try:
                        zip_file.unlink()
                    except Exception as e:
                        logger.warning(f"Failed to remove ZIP file {zip_file}: {e}")
                
                logger.info(f"Removed {zip_files_removed} ZIP files from {zip_storage_dir}")
            
            logger.info(f"Fixtures reset completed - Removed {matches_count} matches, {outcomes_count} outcomes, {zip_files_removed} ZIP files")
            
            return jsonify({
                "success": True,
                "message": "Fixtures data reset successfully",
                "removed": {
                    "matches": matches_count,
                    "outcomes": outcomes_count,
                    "zip_files": zip_files_removed
                }
            })
            
        finally:
            session.close()
            
    except Exception as e:
        logger.error(f"API fixtures reset error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/api-client/status')
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def get_api_client_status():
    """Get API client status and endpoint information"""
    try:
        # Check if we can get API client component status via message bus
        status_data = {
            "api_client_running": False,
            "fastapi_endpoint": {},
            "message_bus_available": bool(api_bp.message_bus),
            "config_manager_available": bool(api_bp.config_manager)
        }
        
        # Try to get current API configuration
        if api_bp.config_manager:
            try:
                api_config = api_bp.config_manager.get_section_config("api") or {}
                status_data["api_config"] = {
                    "fastapi_url": api_config.get("fastapi_url", ""),
                    "api_token_set": bool(api_config.get("api_token", "").strip()),
                    "api_interval": api_config.get("api_interval", 1800),
                    "api_enabled": api_config.get("api_enabled", True)
                }
            except Exception as e:
                status_data["config_error"] = str(e)
        
        # Try to get API endpoints configuration
        if api_bp.config_manager:
            try:
                endpoints_config = api_bp.config_manager.get_section_config("api_endpoints") or {}
                fastapi_endpoint = endpoints_config.get("fastapi_main", {})
                if fastapi_endpoint:
                    status_data["fastapi_endpoint"] = {
                        "url": fastapi_endpoint.get("url", ""),
                        "enabled": fastapi_endpoint.get("enabled", False),
                        "interval": fastapi_endpoint.get("interval", 0),
                        "auth_configured": bool(fastapi_endpoint.get("auth", {}).get("token", "")),
                        "last_request": fastapi_endpoint.get("last_request"),
                        "last_success": fastapi_endpoint.get("last_success"),
                        "consecutive_failures": fastapi_endpoint.get("consecutive_failures", 0),
                        "total_requests": fastapi_endpoint.get("total_requests", 0)
                    }
            except Exception as e:
                status_data["endpoints_error"] = str(e)
        
        return jsonify({
            "success": True,
            "status": status_data
        })
        
    except Exception as e:
        logger.error(f"API client status error: {e}")
        return jsonify({"error": str(e)}), 500


@api_bp.route('/api-client/trigger', methods=['POST'])
@api_bp.auth_manager.require_auth if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
@api_bp.auth_manager.require_admin if hasattr(api_bp, 'auth_manager') and api_bp.auth_manager else login_required
def trigger_api_request():
    """Manually trigger an API request for testing"""
    try:
        data = request.get_json() or {}
        endpoint_name = data.get('endpoint', 'fastapi_main')
        
        # Send manual API request message
        if api_bp.message_bus:
            from ..core.message_bus import MessageBuilder, MessageType
            
            api_request_message = MessageBuilder.api_request(
                sender="web_dashboard",
                endpoint=endpoint_name
            )
            api_bp.message_bus.publish(api_request_message)
            
            logger.info(f"Manual API request triggered for endpoint: {endpoint_name}")
            
            return jsonify({
                "success": True,
                "message": f"API request triggered for endpoint: {endpoint_name}"
            })
        else:
            return jsonify({
                "success": False,
                "error": "Message bus not available"
            }), 500
        
    except Exception as e:
        logger.error(f"API request trigger error: {e}")
        return jsonify({"error": str(e)}), 500