"""
Hauptanwendung für das 3D-Druck-Management-System

Diese Datei initialisiert die Flask-Anwendung und registriert alle Blueprints.
Die eigentlichen Routen sind in den jeweiligen Blueprint-Modulen definiert.
"""

import os
import sys
import logging
import atexit
import signal
import pickle
import hashlib
from datetime import datetime, timedelta
from flask import Flask, render_template, request, jsonify, redirect, url_for, session, abort, send_from_directory, flash
from flask_login import LoginManager, current_user, logout_user, login_required
from flask_wtf import CSRFProtect
from flask_wtf.csrf import CSRFError
from sqlalchemy import event
from contextlib import contextmanager
import threading
import uuid

# ===== MINIMALE SESSION-DATENKLASSE =====
class MinimalSessionInterface:
    """Minimale Session-Implementierung zur Reduzierung der Cookie-Größe"""
    
    @staticmethod
    def reduce_session_data():
        """Reduziert Session-Daten auf absolutes Minimum"""
        from flask import session
        
        # Nur kritische Daten behalten
        essential_keys = ['_user_id', '_id', '_fresh', 'csrf_token']
        
        # Alle nicht-essentiellen Keys entfernen
        keys_to_remove = []
        for key in session.keys():
            if key not in essential_keys:
                keys_to_remove.append(key)
        
        for key in keys_to_remove:
            session.pop(key, None)
    
    @staticmethod
    def get_minimal_session_data():
        """Gibt nur minimale Session-Daten zurück"""
        from flask import session
        return {
            'user_id': session.get('_user_id'),
            'session_id': session.get('_id'),
            'is_fresh': session.get('_fresh', False)
        }

# Globale Session-Interface-Instanz
minimal_session = MinimalSessionInterface()

# ===== SESSION-OPTIMIERUNG =====
class SessionManager:
    """Optimierter Session-Manager für große Session-Daten"""
    
    def __init__(self, app=None):
        self.app = app
        self.session_storage_path = None
        
    def init_app(self, app):
        """Initialisiert den Session-Manager für die Flask-App"""
        self.app = app
        self.session_storage_path = os.path.join(
            app.instance_path, 'sessions'
        )
        os.makedirs(self.session_storage_path, exist_ok=True)
        
    def store_large_session_data(self, key, data):
        """Speichert große Session-Daten im Dateisystem"""
        if not self.session_storage_path:
            return False
            
        try:
            session_id = session.get('session_id')
            if not session_id:
                session_id = hashlib.md5(
                    f"{request.remote_addr}_{datetime.now().isoformat()}".encode()
                ).hexdigest()
                session['session_id'] = session_id
            
            file_path = os.path.join(
                self.session_storage_path, 
                f"{session_id}_{key}.pkl"
            )
            
            with open(file_path, 'wb') as f:
                pickle.dump(data, f)
                
            # Nur Referenz in Session speichern
            session[f"{key}_ref"] = True
            
            return True
        except Exception as e:
            logging.error(f"Fehler beim Speichern der Session-Daten: {e}")
            return False
    
    def load_large_session_data(self, key):
        """Lädt große Session-Daten aus dem Dateisystem"""
        if not self.session_storage_path:
            return None
            
        try:
            session_id = session.get('session_id')
            if not session_id or not session.get(f"{key}_ref"):
                return None
                
            file_path = os.path.join(
                self.session_storage_path,
                f"{session_id}_{key}.pkl"
            )
            
            if not os.path.exists(file_path):
                return None
                
            with open(file_path, 'rb') as f:
                return pickle.load(f)
                
        except Exception as e:
            logging.error(f"Fehler beim Laden der Session-Daten: {e}")
            return None
    
    def cleanup_expired_sessions(self):
        """Bereinigt abgelaufene Session-Dateien"""
        if not self.session_storage_path:
            return
            
        try:
            current_time = datetime.now()
            for filename in os.listdir(self.session_storage_path):
                file_path = os.path.join(self.session_storage_path, filename)
                file_time = datetime.fromtimestamp(os.path.getmtime(file_path))
                
                # Lösche Dateien älter als 24 Stunden
                if current_time - file_time > timedelta(hours=24):
                    os.remove(file_path)
                    
        except Exception as e:
            logging.error(f"Fehler bei Session-Cleanup: {e}")

# Globaler Session-Manager
session_manager = SessionManager()

# ===== PRODUCTION-KONFIGURATION =====
class ProductionConfig:
    """Production-Konfiguration für Mercedes-Benz TBA Marienfelde Air-Gapped Environment
    
    Enthält alle Performance-Optimierungen, die vorher in OptimizedConfig waren,
    plus Production-spezifische Sicherheits- und Compliance-Einstellungen.
    """
    
    # Umgebung
    ENV = 'production'
    DEBUG = False
    TESTING = False
    
    # Performance-Optimierungen (ehemals OptimizedConfig)
    OPTIMIZED_MODE = True
    USE_MINIFIED_ASSETS = True
    DISABLE_ANIMATIONS = True
    LIMIT_GLASSMORPHISM = True
    
    # Sicherheit (SECRET_KEY wird später gesetzt)
    WTF_CSRF_ENABLED = True
    WTF_CSRF_TIME_LIMIT = 3600  # 1 Stunde
    
    # Session-Sicherheit
    SESSION_COOKIE_SECURE = True  # HTTPS erforderlich
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SAMESITE = 'Strict'
    # PERMANENT_SESSION_LIFETIME wird später gesetzt
    
    # Performance-Optimierungen
    SEND_FILE_MAX_AGE_DEFAULT = 31536000  # 1 Jahr Cache für statische Dateien
    TEMPLATES_AUTO_RELOAD = False
    EXPLAIN_TEMPLATE_LOADING = False
    
    # Upload-Beschränkungen
    MAX_CONTENT_LENGTH = 100 * 1024 * 1024  # 100MB für Production
    
    # JSON-Optimierungen
    JSON_SORT_KEYS = False
    JSONIFY_PRETTYPRINT_REGULAR = False
    JSONIFY_MIMETYPE = 'application/json'
    
    # Logging-Level
    LOG_LEVEL = 'INFO'
    
    # Air-Gapped Einstellungen
    OFFLINE_MODE = True
    DISABLE_EXTERNAL_APIS = True
    USE_LOCAL_ASSETS_ONLY = True
    
    # Datenbank-Performance
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_POOL_RECYCLE = 3600
    SQLALCHEMY_POOL_TIMEOUT = 20
    SQLALCHEMY_ENGINE_OPTIONS = {
        'pool_pre_ping': True,
        'pool_recycle': 3600,
        'echo': False
    }
    
    # Security Headers
    SECURITY_HEADERS = {
        'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
        'X-Content-Type-Options': 'nosniff',
        'X-Frame-Options': 'DENY',
        'X-XSS-Protection': '1; mode=block',
        'Referrer-Policy': 'strict-origin-when-cross-origin',
        'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';"
    }
    
    # Mercedes-Benz Corporate Compliance
    COMPANY_NAME = "Mercedes-Benz TBA Marienfelde"
    ENVIRONMENT_NAME = "Production Air-Gapped"
    COMPLIANCE_MODE = True
    AUDIT_LOGGING = True
    
    # Monitoring
    ENABLE_METRICS = True
    ENABLE_HEALTH_CHECKS = True
    ENABLE_PERFORMANCE_MONITORING = True

# ===== DEVELOPMENT-KONFIGURATION =====
class DevelopmentConfig:
    """Development-Konfiguration für lokale Entwicklung
    
    Konsolidiert alle Nicht-Production-Modi (development, default, fallback).
    Optimiert für Entwicklerfreundlichkeit und Debugging.
    """
    
    # Umgebung
    ENV = 'development'
    DEBUG = True
    TESTING = False
    
    # Performance (moderat optimiert für bessere Entwicklererfahrung)
    OPTIMIZED_MODE = False
    USE_MINIFIED_ASSETS = False
    DISABLE_ANIMATIONS = False
    LIMIT_GLASSMORPHISM = False
    
    # Sicherheit (relaxed für Development)
    WTF_CSRF_ENABLED = True
    WTF_CSRF_TIME_LIMIT = 7200  # 2 Stunden für längere Dev-Sessions
    
    # Session-Sicherheit (relaxed)
    SESSION_COOKIE_SECURE = False  # HTTP OK für Development
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SAMESITE = 'Lax'
    
    # Performance (Developer-freundlich)
    SEND_FILE_MAX_AGE_DEFAULT = 1  # Keine Cache für Development
    TEMPLATES_AUTO_RELOAD = True
    EXPLAIN_TEMPLATE_LOADING = True
    
    # Upload-Beschränkungen (generous für Testing)
    MAX_CONTENT_LENGTH = 50 * 1024 * 1024  # 50MB für Development
    
    # JSON (Pretty für Debugging)
    JSON_SORT_KEYS = True
    JSONIFY_PRETTYPRINT_REGULAR = True
    JSONIFY_MIMETYPE = 'application/json'
    
    # Logging-Level
    LOG_LEVEL = 'DEBUG'
    
    # Entwicklungs-Einstellungen
    OFFLINE_MODE = False
    DISABLE_EXTERNAL_APIS = False
    USE_LOCAL_ASSETS_ONLY = False
    
    # Datenbank (Developer-freundlich)
    SQLALCHEMY_TRACK_MODIFICATIONS = True  # Für Debugging
    SQLALCHEMY_POOL_RECYCLE = 1800  # 30 Minuten
    SQLALCHEMY_POOL_TIMEOUT = 30
    SQLALCHEMY_ENGINE_OPTIONS = {
        'pool_pre_ping': True,
        'pool_recycle': 1800,
        'echo': True  # SQL-Logging für Development
    }
    
    # Development-spezifische Einstellungen
    COMPANY_NAME = "MYP Development Environment"
    ENVIRONMENT_NAME = "Development/Testing"
    COMPLIANCE_MODE = False
    AUDIT_LOGGING = False
    
    # Monitoring (minimal für Development)
    ENABLE_METRICS = False
    ENABLE_HEALTH_CHECKS = False
    ENABLE_PERFORMANCE_MONITORING = False

def detect_raspberry_pi():
    """Erkennt ob das System auf einem Raspberry Pi läuft"""
    try:
        with open('/proc/cpuinfo', 'r') as f:
            cpuinfo = f.read()
            if 'Raspberry Pi' in cpuinfo or 'BCM' in cpuinfo:
                return True
    except:
        pass
    
    try:
        import platform
        machine = platform.machine().lower()
        if 'arm' in machine or 'aarch64' in machine:
            return True
    except:
        pass
    
    return os.getenv('FORCE_OPTIMIZED_MODE', '').lower() in ['true', '1', 'yes']

def detect_production_environment():
    """Erkennt ob das System in der Production-Umgebung läuft"""
    # Command-line Argument
    if '--production' in sys.argv:
        return True
    
    # Umgebungsvariable
    env = os.getenv('FLASK_ENV', '').lower()
    if env in ['production', 'prod']:
        return True
    
    # Spezifische Production-Variablen
    if os.getenv('USE_PRODUCTION_CONFIG', '').lower() in ['true', '1', 'yes']:
        return True
    
    # Mercedes-Benz spezifische Erkennung
    if os.getenv('MERCEDES_ENVIRONMENT', '').lower() == 'production':
        return True
    
    # Air-Gapped Environment Detection
    if os.getenv('AIR_GAPPED_MODE', '').lower() in ['true', '1', 'yes']:
        return True
    
    # Hostname-basierte Erkennung
    try:
        import socket
        hostname = socket.gethostname().lower()
        if any(keyword in hostname for keyword in ['prod', 'production', 'live', 'mercedes', 'tba']):
            return True
    except:
        pass
    
    # Automatische Production-Erkennung für Raspberry Pi oder Low-Memory-Systeme
    if detect_raspberry_pi():
        return True
    
    try:
        import psutil
        memory_gb = psutil.virtual_memory().total / (1024**3)
        if memory_gb < 2.0:  # Unter 2GB RAM = wahrscheinlich Production-Umgebung
            return True
    except:
        pass
    
    return False

def get_environment_type():
    """Bestimmt den Umgebungstyp - nur noch production oder development"""
    if detect_production_environment():
        return 'production'
    else:
        return 'development'

# ===== GLOBALE KONFIGURATIONSVARIABLEN =====
# Diese werden später nach den Funktionsdefinitionen gesetzt

# Windows-spezifische Fixes
if os.name == 'nt':
    try:
        from utils.core_system import get_windows_thread_manager
        print("[OK] Windows-Fixes (sichere Version) geladen")
    except ImportError as e:
        get_windows_thread_manager = None
        print(f"[WARN] Windows-Fixes nicht verfügbar: {str(e)}")
else:
    get_windows_thread_manager = None

# Lokale Imports
from models import init_database, create_initial_admin, User, get_db_session
from utils.logging_config import setup_logging, get_logger, log_startup_info
from utils.job_scheduler import JobScheduler, get_job_scheduler
from utils.job_queue_system import queue_manager, start_queue_manager, stop_queue_manager
from utils.utilities_collection import SECRET_KEY, SESSION_LIFETIME

# Blueprints importieren
from blueprints.auth import auth_blueprint
from blueprints.admin_unified import admin_blueprint, admin_api_blueprint
from blueprints.guest import guest_blueprint
from blueprints.calendar import calendar_blueprint
from blueprints.user_management import users_blueprint  # Konsolidierte User-Verwaltung
from blueprints.printers import printers_blueprint
from blueprints.jobs import jobs_blueprint
from blueprints.kiosk import kiosk_blueprint
from blueprints.uploads import uploads_blueprint
from blueprints.sessions import sessions_blueprint
from blueprints.tapo_control import tapo_blueprint  # Tapo-Steckdosen-Steuerung
from blueprints.api import api_blueprint  # API-Endpunkte mit Session-Management
from blueprints.legal_pages import legal_bp  # Rechtliche Seiten (Impressum, Datenschutz, etc.)

# Import der Sicherheits- und Hilfssysteme
from utils.security_suite import init_security

# Logging initialisieren
setup_logging()
log_startup_info()

# Logger für verschiedene Komponenten
app_logger = get_logger("app")

# ===== FLASK-APP INITIALISIERUNG =====
app = Flask(__name__)

# Konfiguration anwenden basierend auf Environment wird später gemacht
# (nach Definition der apply_*_config Funktionen)

# Session-Manager initialisieren
session_manager.init_app(app)

# Login-Manager initialisieren
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'auth.login'
login_manager.login_message = 'Bitte melden Sie sich an, um auf diese Seite zuzugreifen.'
login_manager.login_message_category = 'info'

# CSRF-Schutz initialisieren
csrf = CSRFProtect(app)

# Thread-sichere Caches
_user_cache = {}
_user_cache_lock = threading.RLock()
_printer_status_cache = {}
_printer_status_cache_lock = threading.RLock()

# Cache-Konfiguration
USER_CACHE_TTL = 300  # 5 Minuten
PRINTER_STATUS_CACHE_TTL = 30  # 30 Sekunden

def clear_user_cache(user_id=None):
    """Löscht User-Cache"""
    with _user_cache_lock:
        if user_id:
            _user_cache.pop(user_id, None)
        else:
            _user_cache.clear()

def clear_printer_status_cache():
    """Löscht Drucker-Status-Cache"""
    with _printer_status_cache_lock:
        _printer_status_cache.clear()

# ===== AGGRESSIVE SHUTDOWN HANDLER =====
def aggressive_shutdown_handler(sig, frame):
    """Aggressiver Signal-Handler für sofortiges Herunterfahren bei Strg+C"""
    print("\n[ALERT] STRG+C ERKANNT - SOFORTIGES SHUTDOWN!")
    
    try:
        # Caches leeren
        clear_user_cache()
        clear_printer_status_cache()
        
        # Queue Manager stoppen
        try:
            stop_queue_manager()
            print("[OK] Queue Manager gestoppt")
        except Exception as e:
            print(f"[WARN] Queue Manager Stop fehlgeschlagen: {e}")
        
        # Datenbank-Cleanup
        try:
            from models import _engine, _scoped_session
            if _scoped_session:
                _scoped_session.remove()
            if _engine:
                _engine.dispose()
            print("[OK] Datenbank geschlossen")
        except Exception as e:
            print(f"[WARN] Datenbank-Cleanup fehlgeschlagen: {e}")
    
    except Exception as e:
        print(f"[ERROR] Fehler beim Cleanup: {e}")
    
    print("[STOP] SOFORTIGES PROGRAMM-ENDE")
    os._exit(0)

def register_aggressive_shutdown():
    """Registriert den aggressiven Shutdown-Handler"""
    signal.signal(signal.SIGINT, aggressive_shutdown_handler)
    signal.signal(signal.SIGTERM, aggressive_shutdown_handler)
    
    if os.name == 'nt':
        try:
            signal.signal(signal.SIGBREAK, aggressive_shutdown_handler)
        except AttributeError:
            pass
    else:
        try:
            signal.signal(signal.SIGHUP, aggressive_shutdown_handler)
        except AttributeError:
            pass
    
    atexit.register(lambda: print("[RESTART] Atexit-Handler ausgeführt"))
    print("[ALERT] AGGRESSIVER STRG+C SHUTDOWN-HANDLER AKTIVIERT")

# Shutdown-Handler registrieren
register_aggressive_shutdown()



def apply_production_config(app):
    """Wendet die Production-Konfiguration auf die Flask-App an"""
    app_logger.info("[PRODUCTION] Aktiviere Production-Konfiguration für Mercedes-Benz TBA")
    
    # Dynamische Werte setzen
    from utils.utilities_collection import SECRET_KEY, SESSION_LIFETIME
    ProductionConfig.SECRET_KEY = os.environ.get('SECRET_KEY') or SECRET_KEY
    ProductionConfig.PERMANENT_SESSION_LIFETIME = SESSION_LIFETIME
    
    # Flask-Basis-Konfiguration
    app.config.update({
        "ENV": ProductionConfig.ENV,
        "DEBUG": ProductionConfig.DEBUG,
        "TESTING": ProductionConfig.TESTING,
        "SECRET_KEY": ProductionConfig.SECRET_KEY,
        "WTF_CSRF_ENABLED": ProductionConfig.WTF_CSRF_ENABLED,
        "WTF_CSRF_TIME_LIMIT": ProductionConfig.WTF_CSRF_TIME_LIMIT,
        "SESSION_COOKIE_SECURE": ProductionConfig.SESSION_COOKIE_SECURE,
        "SESSION_COOKIE_HTTPONLY": ProductionConfig.SESSION_COOKIE_HTTPONLY,
        "SESSION_COOKIE_SAMESITE": ProductionConfig.SESSION_COOKIE_SAMESITE,
        "PERMANENT_SESSION_LIFETIME": ProductionConfig.PERMANENT_SESSION_LIFETIME,
        "SEND_FILE_MAX_AGE_DEFAULT": ProductionConfig.SEND_FILE_MAX_AGE_DEFAULT,
        "TEMPLATES_AUTO_RELOAD": ProductionConfig.TEMPLATES_AUTO_RELOAD,
        "EXPLAIN_TEMPLATE_LOADING": ProductionConfig.EXPLAIN_TEMPLATE_LOADING,
        "MAX_CONTENT_LENGTH": ProductionConfig.MAX_CONTENT_LENGTH,
        "JSON_SORT_KEYS": ProductionConfig.JSON_SORT_KEYS,
        "JSONIFY_PRETTYPRINT_REGULAR": ProductionConfig.JSONIFY_PRETTYPRINT_REGULAR,
        "JSONIFY_MIMETYPE": ProductionConfig.JSONIFY_MIMETYPE,
        "SQLALCHEMY_TRACK_MODIFICATIONS": ProductionConfig.SQLALCHEMY_TRACK_MODIFICATIONS,
        "SQLALCHEMY_ENGINE_OPTIONS": ProductionConfig.SQLALCHEMY_ENGINE_OPTIONS
    })
    
    # Jinja2-Umgebung für Production
    app.jinja_env.globals.update({
        'production_mode': True,
        'development_mode': False,
        'optimized_mode': ProductionConfig.OPTIMIZED_MODE,
        'use_minified_assets': ProductionConfig.USE_MINIFIED_ASSETS,
        'disable_animations': ProductionConfig.DISABLE_ANIMATIONS,
        'limit_glassmorphism': ProductionConfig.LIMIT_GLASSMORPHISM,
        'environment_name': ProductionConfig.ENVIRONMENT_NAME,
        'company_name': ProductionConfig.COMPANY_NAME,
        'compliance_mode': ProductionConfig.COMPLIANCE_MODE,
        'offline_mode': ProductionConfig.OFFLINE_MODE,
        'use_local_assets_only': ProductionConfig.USE_LOCAL_ASSETS_ONLY,
        'base_template': 'base-production.html'
    })
    
    app_logger.info(f"[PRODUCTION] ✅ {ProductionConfig.COMPANY_NAME} Konfiguration aktiviert")
    app_logger.info(f"[PRODUCTION] ✅ Environment: {ProductionConfig.ENVIRONMENT_NAME}")
    app_logger.info(f"[PRODUCTION] ✅ Air-Gapped Mode: {ProductionConfig.OFFLINE_MODE}")
    app_logger.info(f"[PRODUCTION] ✅ Compliance Mode: {ProductionConfig.COMPLIANCE_MODE}")
    app_logger.info(f"[PRODUCTION] ✅ Performance Optimized: {ProductionConfig.OPTIMIZED_MODE}")

def apply_development_config(app):
    """Wendet die Development-Konfiguration auf die Flask-App an"""
    app_logger.info("[DEVELOPMENT] Aktiviere Development-Konfiguration")
    
    # Dynamische Werte setzen
    from utils.utilities_collection import SECRET_KEY, SESSION_LIFETIME
    DevelopmentConfig.SECRET_KEY = os.environ.get('SECRET_KEY') or SECRET_KEY
    DevelopmentConfig.PERMANENT_SESSION_LIFETIME = SESSION_LIFETIME
    
    # Flask-Basis-Konfiguration
    app.config.update({
        "ENV": DevelopmentConfig.ENV,
        "DEBUG": DevelopmentConfig.DEBUG,
        "TESTING": DevelopmentConfig.TESTING,
        "SECRET_KEY": DevelopmentConfig.SECRET_KEY,
        "WTF_CSRF_ENABLED": DevelopmentConfig.WTF_CSRF_ENABLED,
        "WTF_CSRF_TIME_LIMIT": DevelopmentConfig.WTF_CSRF_TIME_LIMIT,
        "SESSION_COOKIE_SECURE": DevelopmentConfig.SESSION_COOKIE_SECURE,
        "SESSION_COOKIE_HTTPONLY": DevelopmentConfig.SESSION_COOKIE_HTTPONLY,
        "SESSION_COOKIE_SAMESITE": DevelopmentConfig.SESSION_COOKIE_SAMESITE,
        "PERMANENT_SESSION_LIFETIME": DevelopmentConfig.PERMANENT_SESSION_LIFETIME,
        "SEND_FILE_MAX_AGE_DEFAULT": DevelopmentConfig.SEND_FILE_MAX_AGE_DEFAULT,
        "TEMPLATES_AUTO_RELOAD": DevelopmentConfig.TEMPLATES_AUTO_RELOAD,
        "EXPLAIN_TEMPLATE_LOADING": DevelopmentConfig.EXPLAIN_TEMPLATE_LOADING,
        "MAX_CONTENT_LENGTH": DevelopmentConfig.MAX_CONTENT_LENGTH,
        "JSON_SORT_KEYS": DevelopmentConfig.JSON_SORT_KEYS,
        "JSONIFY_PRETTYPRINT_REGULAR": DevelopmentConfig.JSONIFY_PRETTYPRINT_REGULAR,
        "JSONIFY_MIMETYPE": DevelopmentConfig.JSONIFY_MIMETYPE,
        "SQLALCHEMY_TRACK_MODIFICATIONS": DevelopmentConfig.SQLALCHEMY_TRACK_MODIFICATIONS,
        "SQLALCHEMY_ENGINE_OPTIONS": DevelopmentConfig.SQLALCHEMY_ENGINE_OPTIONS
    })
    
    # Jinja2-Umgebung für Development
    app.jinja_env.globals.update({
        'production_mode': False,
        'development_mode': True,
        'optimized_mode': DevelopmentConfig.OPTIMIZED_MODE,
        'use_minified_assets': DevelopmentConfig.USE_MINIFIED_ASSETS,
        'disable_animations': DevelopmentConfig.DISABLE_ANIMATIONS,
        'limit_glassmorphism': DevelopmentConfig.LIMIT_GLASSMORPHISM,
        'environment_name': DevelopmentConfig.ENVIRONMENT_NAME,
        'company_name': DevelopmentConfig.COMPANY_NAME,
        'compliance_mode': DevelopmentConfig.COMPLIANCE_MODE,
        'offline_mode': DevelopmentConfig.OFFLINE_MODE,
        'use_local_assets_only': DevelopmentConfig.USE_LOCAL_ASSETS_ONLY,
        'base_template': 'base.html'
    })
    
    app_logger.info(f"[DEVELOPMENT] ✅ {DevelopmentConfig.COMPANY_NAME} Konfiguration aktiviert")
    app_logger.info(f"[DEVELOPMENT] ✅ Environment: {DevelopmentConfig.ENVIRONMENT_NAME}")
    app_logger.info(f"[DEVELOPMENT] ✅ Debug Mode: {DevelopmentConfig.DEBUG}")
    app_logger.info(f"[DEVELOPMENT] ✅ SQL Echo: {DevelopmentConfig.SQLALCHEMY_ENGINE_OPTIONS.get('echo', False)}")

# ===== KONFIGURATION ANWENDEN =====
# Jetzt können wir die Funktionen aufrufen, da sie definiert sind
ENVIRONMENT_TYPE = get_environment_type()
USE_PRODUCTION_CONFIG = detect_production_environment()
OFFLINE_MODE = USE_PRODUCTION_CONFIG

app_logger.info(f"[CONFIG] Erkannte Umgebung: {ENVIRONMENT_TYPE}")
app_logger.info(f"[CONFIG] Production-Modus: {USE_PRODUCTION_CONFIG}")

if USE_PRODUCTION_CONFIG:
    apply_production_config(app)
else:
    # Development-Konfiguration (konsolidiert default/fallback)
    app_logger.info("[CONFIG] Verwende Development-Konfiguration")
    apply_development_config(app)

# Umgebungs-spezifische Einstellungen
if OFFLINE_MODE:
    app_logger.info("[CONFIG] ✅ Air-Gapped/Offline-Modus aktiviert")
    app.config['DISABLE_EXTERNAL_REQUESTS'] = True

# Session-Konfiguration
app.config["PERMANENT_SESSION_LIFETIME"] = SESSION_LIFETIME
app.config["WTF_CSRF_ENABLED"] = True
app.config["WTF_CSRF_TIME_LIMIT"] = 3600  # 1 Stunde
app.config["WTF_CSRF_SSL_STRICT"] = False  # Für Development
app.config["WTF_CSRF_CHECK_DEFAULT"] = True
app.config["WTF_CSRF_METHODS"] = ['POST', 'PUT', 'PATCH', 'DELETE']

# CSRF-Schutz initialisieren
csrf = CSRFProtect(app)

# CSRF-Token in Session verfügbar machen
@app.before_request
def csrf_protect():
    """Stellt sicher, dass CSRF-Token verfügbar ist"""
    if request.endpoint and request.endpoint.startswith('static'):
        return
    
    # Guest-API-Endpunkte von CSRF befreien
    if request.path.startswith('/api/guest/'):
        return  # Kein CSRF für Guest-APIs
    
    # Tapo-Hardware-Steuerung von CSRF befreien (Geräte verwenden kein CSRF)
    if request.path.startswith('/tapo/'):
        return  # Kein CSRF für Tapo-Hardware-Steuerung
    
    # Drucker-API-Endpunkte mit Tapo-Integration von CSRF befreien
    tapo_api_paths = [
        '/api/printers/control/',       # Stromsteuerung über PyP100
        '/api/printers/tapo/',          # Alle Tapo-spezifischen APIs
        '/api/printers/force-refresh',  # Force-Refresh (verwendet Tapo-Status)
        '/api/printers/status',         # Status-API (verwendet Tapo-Status)
        '/api/admin/printers/',         # Admin-Printer-APIs (Toggle-Funktion)
    ]
    
    for path in tapo_api_paths:
        if request.path.startswith(path):
            return  # Kein CSRF für Tapo-Hardware-APIs
    
    try:
        from flask_wtf.csrf import generate_csrf
        token = generate_csrf()
        session['_csrf_token'] = token
    except Exception as e:
        app_logger.warning(f"CSRF-Token konnte nicht in Session gesetzt werden: {str(e)}")

# Template-Funktionen für CSRF-Token
@app.template_global()
def csrf_token():
    """CSRF-Token für Templates verfügbar machen."""
    try:
        from flask_wtf.csrf import generate_csrf
        token = generate_csrf()
        app_logger.debug(f"CSRF-Token generiert: {token[:10]}...")
        return token
    except Exception as e:
        app_logger.error(f"CSRF-Token konnte nicht generiert werden: {str(e)}")
        # Fallback: Einfaches Token basierend auf Session
        import secrets
        fallback_token = secrets.token_urlsafe(32)
        app_logger.warning(f"Verwende Fallback-Token: {fallback_token[:10]}...")
        return fallback_token

@app.errorhandler(CSRFError)
def csrf_error(error):
    """Behandelt CSRF-Fehler mit detaillierter Diagnose"""
    # Guest-APIs sollten nie CSRF-Fehler haben
    if request.path.startswith('/api/guest/'):
        app_logger.warning(f"CSRF-Fehler bei Guest-API (sollte nicht passieren): {request.path}")
        return jsonify({
            "success": False,
            "error": "Unerwarteter Sicherheitsfehler bei Guest-API"
        }), 500
    
    app_logger.error(f"CSRF-Fehler für {request.path}: {error.description}")
    app_logger.error(f"Request Headers: {dict(request.headers)}")
    app_logger.error(f"Request Form: {dict(request.form)}")
    
    if request.path.startswith('/api/'):
        # Für API-Anfragen: JSON-Response mit Hilfe
        return jsonify({
            "error": "CSRF-Token ungültig oder fehlt",
            "description": str(error.description),
            "help": "Fügen Sie ein gültiges CSRF-Token zu Ihrer Anfrage hinzu",
            "csrf_token": csrf_token()  # Neues Token für Retry
        }), 400
    else:
        # Für normale Anfragen: Weiterleitung mit Flash-Message
        from flask import flash, redirect
        flash("Sicherheitsfehler: Anfrage wurde abgelehnt. Bitte versuchen Sie es erneut.", "error")
        return redirect(request.url)

# Login-Manager initialisieren
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "auth.login"
login_manager.login_message = "Bitte melden Sie sich an, um auf diese Seite zuzugreifen."

# Session-Manager initialisieren
session_manager.init_app(app)

@login_manager.user_loader
def load_user(user_id):
    """Lädt einen Benutzer für Flask-Login"""
    try:
        with get_db_session() as db_session:
            user = db_session.query(User).filter_by(id=int(user_id)).first()
            if user:
                db_session.expunge(user)
            return user
    except Exception as e:
        app_logger.error(f"Fehler beim Laden des Benutzers {user_id}: {str(e)}")
        return None

# ===== BLUEPRINTS REGISTRIEREN =====
app.register_blueprint(auth_blueprint)
# Vereinheitlichte Admin-Blueprints registrieren
app.register_blueprint(admin_blueprint)
app.register_blueprint(admin_api_blueprint)
app.register_blueprint(guest_blueprint)
app.register_blueprint(calendar_blueprint)
app.register_blueprint(users_blueprint)  # Konsolidierte User-Verwaltung
app.register_blueprint(printers_blueprint)
app.register_blueprint(jobs_blueprint)
app.register_blueprint(kiosk_blueprint)
app.register_blueprint(uploads_blueprint)
app.register_blueprint(sessions_blueprint)
app.register_blueprint(tapo_blueprint)  # Tapo-Steckdosen-Steuerung
app.register_blueprint(api_blueprint)  # Einfache API-Endpunkte
app.register_blueprint(legal_bp)  # Rechtliche Seiten (Impressum, Datenschutz, etc.)

# Energiemonitoring-Blueprints registrieren
from blueprints.energy_monitoring import energy_blueprint, energy_api_blueprint
app.register_blueprint(energy_blueprint)  # Frontend-Routen für Energiemonitoring
app.register_blueprint(energy_api_blueprint)  # API-Endpunkte für Energiedaten

# ===== HILFSSYSTEME INITIALISIEREN =====
init_security(app)

# ===== KONTEXT-PROZESSOREN =====
@app.context_processor
def inject_now():
    """Injiziert die aktuelle Zeit in alle Templates"""
    return {'now': datetime.now}

@app.context_processor
def inject_current_route():
    """
    Stellt current_route für alle Templates bereit.
    
    Verhindert Template-Fehler wenn request.endpoint None ist (z.B. bei 404-Fehlern).
    """
    current_route = getattr(request, 'endpoint', None) or ''
    return {'current_route': current_route}

@app.template_filter('format_datetime')
def format_datetime_filter(value, format='%d.%m.%Y %H:%M'):
    """Template-Filter für Datums-Formatierung"""
    if value is None:
        return ""
    if isinstance(value, str):
        try:
            value = datetime.fromisoformat(value)
        except:
            return value
    return value.strftime(format)

@app.template_global()
def is_optimized_mode():
    """Prüft ob der optimierte Modus aktiv ist"""
    return USE_PRODUCTION_CONFIG

# ===== REQUEST HOOKS =====
@app.before_request
def log_request_info():
    """Loggt Request-Informationen"""
    if request.endpoint != 'static':
        app_logger.debug(f"Request: {request.method} {request.path}")

@app.after_request
def log_response_info(response):
    """Loggt Response-Informationen"""
    if request.endpoint != 'static':
        app_logger.debug(f"Response: {response.status_code}")
    return response

@app.after_request
def minimize_session_cookie(response):
    """Reduziert Session-Cookie automatisch nach jedem Request"""
    if current_user.is_authenticated:
        # Drastische Session-Cookie-Reduktion
        minimal_session.reduce_session_data()
    return response

@app.before_request
def check_session_activity():
    """Prüft Session-Aktivität und meldet inaktive Benutzer ab mit MINIMAL Cookie-Management"""
    if current_user.is_authenticated:
        from utils.utilities_collection import SESSION_LIFETIME
        
        # DRASTISCHE Session-Reduktion - alle nicht-kritischen Daten entfernen
        minimal_session.reduce_session_data()
        
        # Session-Aktivität über externen Store (nicht in Cookie)
        session_data = session_manager.load_large_session_data('activity') or {}
        now = datetime.now()
        
        # Aktivitätsprüfung über externen Store
        last_activity = session_data.get('last_activity')
        if last_activity:
            try:
                last_activity_time = datetime.fromisoformat(last_activity)
                if (now - last_activity_time).total_seconds() > SESSION_LIFETIME.total_seconds():
                    app_logger.info(f"Session abgelaufen für Benutzer {current_user.id}")
                    logout_user()
                    return redirect(url_for('auth.login'))
            except Exception as e:
                app_logger.warning(f"Fehler beim Parsen der Session-Zeit: {e}")
        
        # Aktivität NICHT in Session-Cookie speichern, sondern extern
        session_data['last_activity'] = now.isoformat()
        session_manager.store_large_session_data('activity', session_data)
        
        # Session permanent ohne zusätzliche Daten
        session.permanent = True

# ===== HAUPTROUTEN =====
@app.route("/")
def index():
    """Startseite - leitet zur Login-Seite oder zum Dashboard"""
    if current_user.is_authenticated:
        return redirect(url_for("dashboard"))
    return redirect(url_for("auth.login"))

@app.route("/dashboard")
@login_required
def dashboard():
    """Haupt-Dashboard"""
    return render_template("dashboard.html")

@app.route("/csrf-test")
def csrf_test_page():
    """CSRF-Test-Seite für Diagnose und Debugging"""
    return render_template("csrf_test.html")

@app.route("/api/csrf-test", methods=["POST"])
def csrf_test_api():
    """API-Endpunkt für CSRF-Tests"""
    try:
        # Test-Daten aus Request extrahieren
        if request.is_json:
            data = request.get_json()
            test_data = data.get('test_data', 'Keine Daten')
        else:
            test_data = request.form.get('test_data', 'Keine Daten')
        
        app_logger.info(f"CSRF-Test erfolgreich: {test_data}")
        
        return jsonify({
            "success": True,
            "message": "CSRF-Test erfolgreich",
            "data": test_data,
            "timestamp": datetime.now().isoformat()
        }), 200
        
    except Exception as e:
        app_logger.error(f"CSRF-Test Fehler: {str(e)}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500

@app.route("/admin")
@login_required
def admin():
    """Admin-Dashboard"""
    if not current_user.is_admin:
        abort(403)
    return redirect(url_for("admin.admin_dashboard"))

# ===== HAUPTSEITEN =====

@app.route("/printers")
@login_required
def printers_page():
    """Zeigt die Übersichtsseite für Drucker an mit Server-Side Rendering."""
    try:
        from utils.hardware_integration import get_tapo_controller
        from models import get_db_session, Printer
        
        # Drucker-Daten server-side laden
        db_session = get_db_session()
        all_printers = db_session.query(Printer).filter(Printer.active == True).all()
        
        # Live-Status direkt über TapoController abrufen
        tapo_controller = get_tapo_controller()
        
        # Drucker-Daten mit Status anreichern
        printers_with_status = []
        for printer in all_printers:
            printer_info = {
                'id': printer.id,
                'name': printer.name,
                'model': printer.model or 'Unbekannt',
                'location': printer.location or 'Unbekannt',
                'ip_address': printer.ip_address,
                'plug_ip': printer.plug_ip,
                'active': printer.active,
                'status': 'offline'
            }
            
            # Status direkt über TapoController prüfen und in DB persistieren
            if printer.plug_ip:
                try:
                    reachable, plug_status = tapo_controller.check_outlet_status(
                        printer.plug_ip, printer_id=printer.id
                    )
                    
                    # Drucker-Status basierend auf Steckdosen-Status aktualisieren
                    if not reachable:
                        # Nicht erreichbar = offline
                        printer.status = 'offline'
                        status_text = 'Offline'
                        status_color = 'red'
                    elif plug_status == 'on':
                        # Steckdose an = belegt
                        printer.status = 'busy'
                        status_text = 'Belegt'
                        status_color = 'green'
                    elif plug_status == 'off':
                        # Steckdose aus = verfügbar
                        printer.status = 'idle'
                        status_text = 'Verfügbar'
                        status_color = 'gray'
                    else:
                        # Unbekannter Status = offline
                        printer.status = 'offline'
                        status_text = 'Unbekannt'
                        status_color = 'red'
                    
                    # Zeitstempel aktualisieren und in DB speichern
                    printer.last_checked = datetime.now()
                    printer.updated_at = datetime.now()
                    
                    # Status-Änderung protokollieren (nur bei tatsächlicher Änderung)
                    from models import PlugStatusLog
                    current_db_status = printer.status
                    log_status = 'connected' if reachable else 'disconnected'
                    if plug_status == 'on':
                        log_status = 'on'
                    elif plug_status == 'off':
                        log_status = 'off'
                    
                    # Nur loggen wenn sich der Status geändert hat (vereinfachte Prüfung)
                    try:
                        PlugStatusLog.log_status_change(
                            printer_id=printer.id,
                            status=log_status,
                            source='system',
                            ip_address=printer.plug_ip,
                            notes="Automatische Status-Prüfung beim Laden der Drucker-Seite"
                        )
                        app_logger.debug(f"📊 Auto-Status protokolliert: Drucker {printer.id} -> {log_status}")
                    except Exception as log_error:
                        app_logger.error(f"❌ Fehler beim Auto-Protokollieren: {str(log_error)}")
                    
                    printer_info.update({
                        'plug_status': plug_status,
                        'plug_reachable': reachable,
                        'can_control': reachable,
                        'status': printer.status,
                        'last_checked': datetime.now().isoformat()
                    })
                    
                    # Status-Display für UI
                    printer_info['status_display'] = {
                        'text': status_text, 
                        'color': status_color
                    }
                except Exception as e:
                    printer_info.update({
                        'plug_status': 'unknown',
                        'plug_reachable': False,
                        'can_control': False,
                        'error': str(e),
                        'status_display': {'text': 'Fehler', 'color': 'red'}
                    })
            else:
                printer_info.update({
                    'plug_status': 'no_plug',
                    'plug_reachable': False,
                    'can_control': False,
                    'status_display': {'text': 'Keine Steckdose', 'color': 'gray'}
                })
            
            printers_with_status.append(printer_info)
        
        # Alle Status-Updates in die Datenbank committen
        try:
            db_session.commit()
            app_logger.debug(f"✅ Status-Updates für {len(printers_with_status)} Drucker erfolgreich gespeichert")
        except Exception as commit_error:
            app_logger.error(f"❌ Fehler beim Speichern der Status-Updates: {str(commit_error)}")
            db_session.rollback()
        
        # Einzigartige Werte für Filter
        models = list(set([p['model'] for p in printers_with_status if p['model'] != 'Unbekannt']))
        locations = list(set([p['location'] for p in printers_with_status if p['location'] != 'Unbekannt']))
        
        db_session.close()
        
        return render_template("printers.html", 
                              printers=printers_with_status,
                              models=models,
                              locations=locations,
                              no_javascript=True)
        
    except Exception as e:
        app_logger.error(f"Fehler beim Laden der Drucker-Seite: {str(e)}")
        return render_template("printers.html", 
                              printers=[],
                              models=[],
                              locations=[],
                              error=str(e),
                              no_javascript=True)

@app.route("/printers/control", methods=["POST"])
@login_required
def printer_control():
    """Server-Side Drucker-Steuerung ohne JavaScript."""
    try:
        from utils.hardware_integration import get_tapo_controller
        from models import get_db_session, Printer
        
        printer_id = request.form.get('printer_id')
        action = request.form.get('action')  # 'on' oder 'off'
        
        if not printer_id or not action:
            flash('Ungültige Parameter für Drucker-Steuerung', 'error')
            return redirect(url_for('printers_page'))
        
        if action not in ['on', 'off']:
            flash('Ungültige Aktion. Nur "on" oder "off" erlaubt.', 'error')
            return redirect(url_for('printers_page'))
        
        # Drucker aus Datenbank laden
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == int(printer_id)).first()
        
        if not printer:
            flash('Drucker nicht gefunden', 'error')
            db_session.close()
            return redirect(url_for('printers_page'))
        
        if not printer.plug_ip:
            flash('Keine Steckdose für diesen Drucker konfiguriert', 'error')
            db_session.close()
            return redirect(url_for('printers_page'))
        
        # Erst Erreichbarkeit der Steckdose prüfen
        tapo_controller = get_tapo_controller()
        
        # Prüfe ob Steckdose erreichbar ist
        reachable, current_status = tapo_controller.check_outlet_status(printer.plug_ip, printer_id=int(printer_id))
        if not reachable:
            # Steckdose nicht erreichbar = Drucker offline
            printer.status = 'offline'
            printer.last_checked = datetime.now()
            printer.updated_at = datetime.now()
            
            # Status-Änderung protokollieren
            from models import PlugStatusLog
            try:
                PlugStatusLog.log_status_change(
                    printer_id=int(printer_id),
                    status='disconnected',
                    source='system',
                    user_id=current_user.id,
                    ip_address=printer.plug_ip,
                    error_message=f"Steckdose {printer.plug_ip} nicht erreichbar",
                    notes=f"Erreichbarkeitsprüfung durch {current_user.name} fehlgeschlagen"
                )
                app_logger.debug(f"📊 Offline-Status protokolliert: Drucker {printer_id} -> disconnected")
            except Exception as log_error:
                app_logger.error(f"❌ Fehler beim Protokollieren des Offline-Status: {str(log_error)}")
            
            db_session.commit()
            
            flash(f'Steckdose nicht erreichbar - Drucker als offline markiert', 'error')
            app_logger.warning(f"⚠️ Steckdose {printer.plug_ip} für Drucker {printer_id} nicht erreichbar")
            db_session.close()
            return redirect(url_for('printers_page'))
        
        # Steckdose erreichbar - Steuerung ausführen
        state = action == 'on'
        success = tapo_controller.toggle_plug(printer.plug_ip, state)
        
        if success:
            # Drucker-Status basierend auf Steckdosen-Aktion aktualisieren
            if action == 'on':
                # Steckdose an = Drucker belegt (busy)
                printer.status = 'busy'
                status_text = "belegt"
                plug_status = 'on'
            else:
                # Steckdose aus = Drucker verfügbar (idle)
                printer.status = 'idle'
                status_text = "verfügbar"
                plug_status = 'off'
            
            # Zeitstempel der letzten Überprüfung aktualisieren
            printer.last_checked = datetime.now()
            printer.updated_at = datetime.now()
            
            # Status-Änderung in PlugStatusLog protokollieren mit Energiedaten
            from models import PlugStatusLog
            try:
                # Energiedaten abrufen falls verfügbar
                energy_data = {}
                try:
                    reachable, current_status = tapo_controller.check_outlet_status(printer.plug_ip, printer_id=int(printer_id))
                    if reachable:
                        # Versuche Energiedaten zu holen (falls P110)
                        extra_info = tapo_controller._get_extra_device_info(printer.plug_ip)
                        if extra_info:
                            energy_data = {
                                'power_consumption': extra_info.get('power_consumption'),
                                'voltage': extra_info.get('voltage'),
                                'current': extra_info.get('current'),
                                'firmware_version': extra_info.get('firmware_version')
                            }
                except Exception as energy_error:
                    app_logger.debug(f"⚡ Energiedaten für {printer.plug_ip} nicht verfügbar: {str(energy_error)}")
                
                action_text = "eingeschaltet" if action == 'on' else "ausgeschaltet"
                PlugStatusLog.log_status_change(
                    printer_id=int(printer_id),
                    status=plug_status,
                    source='manual',
                    user_id=current_user.id,
                    ip_address=printer.plug_ip,
                    power_consumption=energy_data.get('power_consumption'),
                    voltage=energy_data.get('voltage'),
                    current=energy_data.get('current'),
                    firmware_version=energy_data.get('firmware_version'),
                    notes=f"Manuell {action_text} durch {current_user.name}"
                )
                app_logger.debug(f"📊 Status-Änderung mit Energiedaten protokolliert: Drucker {printer_id} -> {plug_status}")
            except Exception as log_error:
                app_logger.error(f"❌ Fehler beim Protokollieren der Status-Änderung: {str(log_error)}")
            
            # Änderungen in Datenbank speichern
            db_session.commit()
            
            action_text = "eingeschaltet" if action == 'on' else "ausgeschaltet"
            flash(f'Drucker erfolgreich {action_text} - Status: {status_text}', 'success')
            app_logger.info(f"✅ Drucker {printer_id} erfolgreich {action_text} durch {current_user.name} - Status: {status_text}")
        else:
            action_text = "einschalten" if action == 'on' else "ausschalten"
            flash(f'Fehler beim {action_text} der Steckdose', 'error')
            app_logger.error(f"❌ Fehler beim {action_text} von Drucker {printer_id}")
        
        db_session.close()
        
        return redirect(url_for('printers_page'))
        
    except Exception as e:
        app_logger.error(f"Unerwarteter Fehler bei Drucker-Steuerung: {str(e)}")
        flash(f'Systemfehler: {str(e)}', 'error')
        return redirect(url_for('printers_page'))

@app.route("/jobs")
@login_required
def jobs_page():
    """Zeigt die Übersichtsseite für Druckaufträge an."""
    return render_template("jobs.html")

@app.route("/jobs/new")
@login_required
def new_job_page():
    """Zeigt die Seite zum Erstellen neuer Druckaufträge an."""
    return render_template("jobs.html")

@app.route("/stats")
@login_required
def stats_page():
    """Zeigt die Statistiken-Seite an"""
    return render_template("stats.html", title="Statistiken")

# ===== API-ENDPUNKTE FÜR FRONTEND-KOMPATIBILITÄT =====
# Jobs-API wird über Blueprint gehandhabt - keine doppelten Routen hier

@app.route('/sw.js')
def service_worker():
    """Service Worker für PWA-Funktionalität"""
    return send_from_directory('static', 'sw.js', mimetype='application/javascript')

@app.route("/api/jobs/<int:job_id>/start", methods=["POST"])
@login_required
def api_start_job(job_id):
    """API-Endpunkt für Job-Start - leitet an Jobs-Blueprint weiter"""
    from blueprints.jobs import start_job
    return start_job(job_id)

@app.route("/api/jobs/<int:job_id>/pause", methods=["POST"])
@login_required
def api_pause_job(job_id):
    """API-Endpunkt für Job-Pause - leitet an Jobs-Blueprint weiter"""
    from blueprints.jobs import pause_job
    return pause_job(job_id)

@app.route("/api/jobs/<int:job_id>/resume", methods=["POST"])
@login_required
def api_resume_job(job_id):
    """API-Endpunkt für Job-Resume - leitet an Jobs-Blueprint weiter"""
    from blueprints.jobs import resume_job
    return resume_job(job_id)

@app.route("/api/jobs/<int:job_id>/finish", methods=["POST"])
@login_required
def api_finish_job(job_id):
    """API-Endpunkt für Job-Finish - leitet an Jobs-Blueprint weiter"""
    from blueprints.jobs import finish_job
    return finish_job(job_id)

@app.route("/api/printers", methods=["GET"])
@login_required
def api_get_printers():
    """API-Endpunkt für Drucker-Liste mit konsistenter Response-Struktur
    
    Query-Parameter:
    - include_inactive: 'true' um auch inaktive Drucker anzuzeigen (default: 'false')
    - show_all: 'true' um ALLE Drucker anzuzeigen, unabhängig vom Status (default: 'false')
    """
    try:
        from models import get_db_session, Printer
        
        # Query-Parameter auslesen - Standardmäßig nur aktive TBA Marienfelde Drucker
        include_inactive = request.args.get('include_inactive', 'false').lower() == 'true'
        show_all = request.args.get('show_all', 'false').lower() == 'true'
        
        db_session = get_db_session()
        
        # Basis-Query - NUR aktive TBA Marienfelde Drucker (die korrekten 6)
        query = db_session.query(Printer)
        
        if show_all:
            # Nur wenn explizit angefordert: ALLE Drucker zeigen
            pass  # Keine Filter
        else:
            # Standard: Nur aktive TBA Marienfelde Drucker mit korrekten Namen
            correct_names = ['Drucker 1', 'Drucker 2', 'Drucker 3', 'Drucker 4', 'Drucker 5', 'Drucker 6']
            query = query.filter(
                Printer.location == 'TBA Marienfelde',
                Printer.active == True,
                Printer.name.in_(correct_names)
            )
            
            if not include_inactive:
                # Zusätzlich: Keine offline/unreachable Drucker (außer wenn explizit gewünscht)
                pass  # Status-Filter wird später in der UI angewendet
        
        printers = query.all()
        
        printer_list = []
        for printer in printers:
            # Status-Bestimmung: Wenn nicht erreichbar, dann "offline"
            status = printer.status or "offline"
            
            # Zusätzliche Status-Informationen
            is_reachable = status not in ["offline", "unreachable", "error"]
            
            printer_dict = {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model or "Unbekanntes Modell",
                "location": printer.location or "Unbekannter Standort", 
                "status": status,
                "ip_address": printer.ip_address,
                "plug_ip": printer.plug_ip,
                "active": getattr(printer, 'active', True),
                "is_reachable": is_reachable,  # Zusätzliches Feld für UI
                "is_selectable": True,  # WICHTIG: Alle Drucker sind auswählbar!
                "created_at": printer.created_at.isoformat() if printer.created_at else datetime.now().isoformat(),
                "last_checked": printer.last_checked.isoformat() if printer.last_checked else None,
                "display_status": f"{printer.name} - {status.title()}"  # Für Dropdown-Anzeige
            }
            printer_list.append(printer_dict)
        
        db_session.close()
        
        app_logger.info(f"✅ API: {len(printer_list)} Drucker abgerufen (include_inactive={include_inactive})")
        
        # Konsistente Response-Struktur wie erwartet
        return jsonify({
            "success": True,
            "printers": printer_list,
            "count": len(printer_list),
            "message": "Drucker erfolgreich geladen",
            "filters": {
                "include_inactive": include_inactive,
                "show_all": show_all
            }
        })
        
    except Exception as e:
        app_logger.error(f"❌ API-Fehler beim Abrufen der Drucker: {str(e)}")
        return jsonify({
            "success": False,
            "error": "Fehler beim Laden der Drucker", 
            "details": str(e),
            "printers": [],
            "count": 0
        }), 500

@app.route("/api/printers/status", methods=["GET"])
@login_required
def api_get_printer_status():
    """API-Endpunkt für Drucker-Status mit verbessertem Status-Management"""
    try:
        # Verwende den konsolidierten Hardware Integration Monitor
        from utils.hardware_integration import printer_monitor
        
        # Status für alle Drucker abrufen
        status_data = printer_monitor.get_live_printer_status()
        status_list = list(status_data.values())
        
        # Erweitere Status mit UI-freundlichen Informationen
        for status in status_list:
            # Status-Display-Informationen hinzufügen
            plug_status = status.get("plug_status", "unknown")
            if plug_status in printer_monitor.STATUS_DISPLAY:
                status["status_display"] = printer_monitor.STATUS_DISPLAY[plug_status]
            else:
                status["status_display"] = {
                    "text": "Unbekannt",
                    "color": "gray",
                    "icon": "question"
                }
        
        app_logger.info(f"✅ API: Status für {len(status_list)} Drucker abgerufen")
        
        # Erfolgreiche Response mit konsistenter Struktur
        return jsonify({
            "success": True,
            "printers": status_list,
            "count": len(status_list),
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        app_logger.error(f"❌ API-Fehler beim Abrufen des Drucker-Status: {str(e)}", exc_info=True)
        
        # Fallback: Mindestens die Drucker-Grunddaten zurückgeben
        try:
            from models import get_db_session, Printer
            db_session = get_db_session()
            printers = db_session.query(Printer).all()
            
            basic_status = []
            for printer in printers:
                basic_status.append({
                    "id": printer.id,
                    "name": printer.name,
                    "location": printer.location,
                    "model": printer.model,
                    "plug_status": "unreachable",
                    "plug_reachable": False,
                    "has_plug": bool(printer.plug_ip),
                    "error": "Status-Manager nicht verfügbar"
                })
            
            db_session.close()
            
            return jsonify({
                "success": False,
                "error": "Eingeschränkte Status-Informationen",
                "printers": basic_status,
                "count": len(basic_status),
                "timestamp": datetime.now().isoformat()
            })
            
        except:
            return jsonify({
                "success": False,
                "error": "Fehler beim Laden des Drucker-Status", 
                "details": str(e),
                "printers": [],
                "count": 0
            }), 500

@app.route("/api/health", methods=["GET"])
def api_health_check():
    """Einfacher Health-Check für Monitoring"""
    try:
        from models import get_db_session
        
        # Datenbank-Verbindung testen
        db_session = get_db_session()
        db_session.execute("SELECT 1")
        db_session.close()
        
        return jsonify({
            "status": "healthy",
            "timestamp": datetime.now().isoformat(),
            "version": "1.0.0",
            "services": {
                "database": "online",
                "authentication": "online"
            }
        })
        
    except Exception as e:
        app_logger.error(f"❌ Health-Check fehlgeschlagen: {str(e)}")
        return jsonify({
            "status": "unhealthy",
            "timestamp": datetime.now().isoformat(),
            "error": str(e)
        }), 503

@app.route("/api/version", methods=["GET"])
def api_version():
    """API-Version und System-Info"""
    return jsonify({
        "version": "1.0.0",
        "name": "MYP - Manage Your Printer",
        "description": "3D-Drucker-Verwaltung mit Smart-Steckdosen",
        "build": datetime.now().strftime("%Y%m%d"),
        "environment": get_environment_type()
    })

@app.route("/api/stats", methods=['GET'])
@login_required
def api_stats():
    """
    Allgemeine System-Statistiken API-Endpunkt.
    
    Stellt grundlegende Statistiken über das System zur Verfügung.
    """
    try:
        from models import get_db_session, User, Printer, Job
        
        db_session = get_db_session()
        try:
            # Grundlegende Counts
            total_users = db_session.query(User).count()
            total_printers = db_session.query(Printer).count()
            total_jobs = db_session.query(Job).count()
            
            # Aktive Jobs
            active_jobs = db_session.query(Job).filter(
                Job.status.in_(['pending', 'printing', 'paused'])
            ).count()
            
            # Abgeschlossene Jobs heute
            from datetime import date
            today = date.today()
            completed_today = db_session.query(Job).filter(
                Job.status == 'completed',
                Job.updated_at >= today
            ).count()
            
            # Online-Drucker (aktive Drucker)
            online_printers = db_session.query(Printer).filter(
                Printer.active == True
            ).count()
        finally:
            db_session.close()
        
        stats = {
            'total_users': total_users,
            'total_printers': total_printers,
            'total_jobs': total_jobs,
            'active_jobs': active_jobs,
            'completed_today': completed_today,
            'online_printers': online_printers,
            'timestamp': datetime.now().isoformat()
        }
        
        app_logger.info(f"✅ API-Statistiken abgerufen von {current_user.username}")
        
        return jsonify({
            'success': True,
            'stats': stats,
            'message': 'Statistiken erfolgreich geladen'
        })
        
    except Exception as e:
        app_logger.error(f"❌ Fehler beim Abrufen der API-Statistiken: {str(e)}")
        return jsonify({
            'success': False,
            'error': 'Fehler beim Laden der Statistiken',
            'details': str(e)
        }), 500

# Statische Seiten
@app.route("/privacy")
def privacy():
    """Datenschutzerklärung"""
    return render_template("privacy.html")

@app.route("/terms")
def terms():
    """Nutzungsbedingungen"""
    return render_template("terms.html")

@app.route("/imprint")
def imprint():
    """Impressum"""
    return render_template("imprint.html")

@app.route("/legal")
def legal():
    """Rechtliche Hinweise - Weiterleitung zum Impressum"""
    return redirect(url_for("imprint"))

# ===== FEHLERBEHANDLUNG =====
@app.errorhandler(400)
def bad_request_error(error):
    """400-Fehlerseite - Ungültige Anfrage"""
    app_logger.warning(f"Bad Request (400): {request.url} - {str(error)}")
    if request.is_json:
        return jsonify({
            "error": "Ungültige Anfrage",
            "message": "Die Anfrage konnte nicht verarbeitet werden",
            "status_code": 400
        }), 400
    return render_template('errors/400.html'), 400

@app.errorhandler(401)
def unauthorized_error(error):
    """401-Fehlerseite - Nicht autorisiert"""
    app_logger.warning(f"Unauthorized (401): {request.url} - User: {getattr(current_user, 'username', 'Anonymous')}")
    if request.is_json:
        return jsonify({
            "error": "Nicht autorisiert",
            "message": "Anmeldung erforderlich",
            "status_code": 401
        }), 401
    return redirect(url_for('auth.login'))

@app.errorhandler(403)
def forbidden_error(error):
    """403-Fehlerseite - Zugriff verweigert"""
    app_logger.warning(f"Forbidden (403): {request.url} - User: {getattr(current_user, 'username', 'Anonymous')}")
    if request.is_json:
        return jsonify({
            "error": "Zugriff verweigert",
            "message": "Sie haben keine Berechtigung für diese Aktion",
            "status_code": 403
        }), 403
    
    try:
        return render_template('errors/403.html'), 403
    except Exception as template_error:
        # Fallback bei Template-Fehlern
        app_logger.error(f"Template-Fehler in 403-Handler: {str(template_error)}")
        return f"<h1>403 - Zugriff verweigert</h1><p>Sie haben keine Berechtigung für diese Aktion.</p>", 403

@app.errorhandler(404)
def not_found_error(error):
    """404-Fehlerseite - Seite nicht gefunden"""
    app_logger.info(f"Not Found (404): {request.url}")
    if request.is_json:
        return jsonify({
            "error": "Nicht gefunden",
            "message": "Die angeforderte Ressource wurde nicht gefunden",
            "status_code": 404
        }), 404
    
    try:
        return render_template('errors/404.html'), 404
    except Exception as template_error:
        # Fallback bei Template-Fehlern
        app_logger.error(f"Template-Fehler in 404-Handler: {str(template_error)}")
        return f"<h1>404 - Nicht gefunden</h1><p>Die angeforderte Seite wurde nicht gefunden.</p>", 404

@app.errorhandler(405)
def method_not_allowed_error(error):
    """405-Fehlerseite - Methode nicht erlaubt"""
    app_logger.warning(f"Method Not Allowed (405): {request.method} {request.url}")
    if request.is_json:
        return jsonify({
            "error": "Methode nicht erlaubt",
            "message": f"Die HTTP-Methode {request.method} ist für diese URL nicht erlaubt",
            "status_code": 405
        }), 405
    return render_template('errors/405.html'), 405

@app.errorhandler(413)
def payload_too_large_error(error):
    """413-Fehlerseite - Datei zu groß"""
    app_logger.warning(f"Payload Too Large (413): {request.url}")
    if request.is_json:
        return jsonify({
            "error": "Datei zu groß",
            "message": "Die hochgeladene Datei ist zu groß",
            "status_code": 413
        }), 413
    return render_template('errors/413.html'), 413

@app.errorhandler(429)
def rate_limit_error(error):
    """429-Fehlerseite - Zu viele Anfragen"""
    app_logger.warning(f"Rate Limit Exceeded (429): {request.url} - IP: {request.remote_addr}")
    if request.is_json:
        return jsonify({
            "error": "Zu viele Anfragen",
            "message": "Sie haben zu viele Anfragen gesendet. Bitte versuchen Sie es später erneut",
            "status_code": 429
        }), 429
    return render_template('errors/429.html'), 429

@app.errorhandler(500)
def internal_error(error):
    """500-Fehlerseite - Interner Serverfehler"""
    import traceback
    error_id = datetime.now().strftime("%Y%m%d_%H%M%S")
    
    # Detailliertes Logging für Debugging
    app_logger.error(f"Internal Server Error (500) - ID: {error_id}")
    app_logger.error(f"URL: {request.url}")
    app_logger.error(f"Method: {request.method}")
    app_logger.error(f"User: {getattr(current_user, 'username', 'Anonymous')}")
    app_logger.error(f"Error: {str(error)}")
    app_logger.error(f"Traceback: {traceback.format_exc()}")
    
    if request.is_json:
        return jsonify({
            "error": "Interner Serverfehler",
            "message": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut",
            "error_id": error_id,
            "status_code": 500
        }), 500
    
    try:
        return render_template('errors/500.html', error_id=error_id), 500
    except Exception as template_error:
        # Fallback bei Template-Fehlern
        app_logger.error(f"Template-Fehler in 500-Handler: {str(template_error)}")
        return f"<h1>500 - Interner Serverfehler</h1><p>Ein unerwarteter Fehler ist aufgetreten. Fehler-ID: {error_id}</p>", 500

@app.errorhandler(502)
def bad_gateway_error(error):
    """502-Fehlerseite - Bad Gateway"""
    app_logger.error(f"Bad Gateway (502): {request.url}")
    if request.is_json:
        return jsonify({
            "error": "Gateway-Fehler",
            "message": "Der Server ist vorübergehend nicht verfügbar",
            "status_code": 502
        }), 502
    return render_template('errors/502.html'), 502

@app.errorhandler(503)
def service_unavailable_error(error):
    """503-Fehlerseite - Service nicht verfügbar"""
    app_logger.error(f"Service Unavailable (503): {request.url}")
    if request.is_json:
        return jsonify({
            "error": "Service nicht verfügbar",
            "message": "Der Service ist vorübergehend nicht verfügbar. Bitte versuchen Sie es später erneut",
            "status_code": 503
        }), 503
    return render_template('errors/503.html'), 503

@app.errorhandler(505)
def http_version_not_supported_error(error):
    """505-Fehlerseite - HTTP-Version nicht unterstützt"""
    app_logger.error(f"HTTP Version Not Supported (505): {request.url}")
    if request.is_json:
        return jsonify({
            "error": "HTTP-Version nicht unterstützt",
            "message": "Die verwendete HTTP-Version wird vom Server nicht unterstützt",
            "status_code": 505
        }), 505
    return render_template('errors/505.html'), 505

# Allgemeiner Exception-Handler für unbehandelte Ausnahmen
@app.errorhandler(Exception)
def handle_exception(error):
    """Allgemeiner Handler für unbehandelte Ausnahmen"""
    import traceback
    error_id = datetime.now().strftime("%Y%m%d_%H%M%S")
    
    # Detailliertes Logging
    app_logger.error(f"Unhandled Exception - ID: {error_id}")
    app_logger.error(f"URL: {request.url}")
    app_logger.error(f"Method: {request.method}")
    app_logger.error(f"User: {getattr(current_user, 'username', 'Anonymous')}")
    app_logger.error(f"Exception Type: {type(error).__name__}")
    app_logger.error(f"Exception: {str(error)}")
    app_logger.error(f"Traceback: {traceback.format_exc()}")
    
    # Für HTTP-Exceptions die ursprüngliche Behandlung verwenden
    if hasattr(error, 'code'):
        return error
    
    # Für alle anderen Exceptions als 500 behandeln
    if request.is_json:
        return jsonify({
            "error": "Unerwarteter Fehler",
            "message": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut",
            "error_id": error_id,
            "status_code": 500
        }), 500
    
    try:
        return render_template('errors/500.html', error_id=error_id), 500
    except Exception as template_error:
        # Fallback bei Template-Fehlern
        app_logger.error(f"Template-Fehler im Exception-Handler: {str(template_error)}")
        return f"<h1>500 - Unerwarteter Fehler</h1><p>Ein unerwarteter Fehler ist aufgetreten. Fehler-ID: {error_id}</p>", 500

# ===== APP-FACTORY =====
def create_app(config_name=None):
    """
    Flask-App-Factory für Tests und modulare Initialisierung
    
    Args:
        config_name: 'production', 'development' oder None (auto-detect)
    
    Returns:
        Flask: Konfigurierte Flask-App-Instanz
    """
    # Bestimme Konfiguration
    if config_name is None:
        config_name = get_environment_type()
    
    # Setze Environment-Variablen basierend auf config_name
    if config_name == 'production':
        os.environ['FLASK_ENV'] = 'production'
        os.environ['USE_PRODUCTION_CONFIG'] = 'true'
    else:
        os.environ['FLASK_ENV'] = 'development'
        os.environ['USE_PRODUCTION_CONFIG'] = 'false'
    
    # Globale Variablen neu setzen
    global ENVIRONMENT_TYPE, USE_PRODUCTION_CONFIG, OFFLINE_MODE
    ENVIRONMENT_TYPE = config_name
    USE_PRODUCTION_CONFIG = (config_name == 'production')
    OFFLINE_MODE = USE_PRODUCTION_CONFIG
    
    # App-Konfiguration anwenden
    if USE_PRODUCTION_CONFIG:
        apply_production_config(app)
        app_logger.info(f"[FACTORY] ✅ Production-Konfiguration angewendet")
    else:
        apply_development_config(app)
        app_logger.info(f"[FACTORY] ✅ Development-Konfiguration angewendet")
    
    # Session-Manager initialisieren
    session_manager.init_app(app)
    
    # Sicherheitssuite initialisieren
    try:
        init_security(app)
        app_logger.info("[FACTORY] ✅ Sicherheitssuite initialisiert")
    except Exception as e:
        app_logger.warning(f"[FACTORY] ⚠️ Sicherheitssuite-Fehler: {e}")
    
    app_logger.info(f"[FACTORY] 🏭 Flask-App erstellt ({config_name})")
    return app

# ===== HAUPTFUNKTION =====
def main():
    """Hauptfunktion zum Starten der Anwendung"""
    try:
        # Umgebungsinfo loggen
        app_logger.info(f"[STARTUP] 🚀 Starte MYP {ENVIRONMENT_TYPE.upper()}-Umgebung")
        app_logger.info(f"[STARTUP] 🏢 {getattr(ProductionConfig, 'COMPANY_NAME', 'Mercedes-Benz TBA Marienfelde')}")
        app_logger.info(f"[STARTUP] 🔒 Air-Gapped: {OFFLINE_MODE or getattr(ProductionConfig, 'OFFLINE_MODE', False)}")
        
        # Production-spezifische Initialisierung
        if USE_PRODUCTION_CONFIG:
            app_logger.info("[PRODUCTION] Initialisiere Production-Systeme...")
            
            # Performance-Monitoring aktivieren
            if getattr(ProductionConfig, 'ENABLE_PERFORMANCE_MONITORING', False):
                try:
                    from utils.monitoring_analytics import performance_tracker
                    # Performance monitoring initialized via global instance
                    app_logger.info("[PRODUCTION] ✅ Performance-Monitoring aktiviert")
                except ImportError:
                    app_logger.warning("[PRODUCTION] ⚠️ Performance-Monitoring nicht verfügbar")
            
            # Health-Checks aktivieren
            if getattr(ProductionConfig, 'ENABLE_HEALTH_CHECKS', False):
                try:
                    from utils.monitoring_analytics import get_health_check
                    # Simple health check initialization
                    app_logger.info("[PRODUCTION] ✅ Health-Checks aktiviert")
                except ImportError:
                    app_logger.warning("[PRODUCTION] ⚠️ Health-Checks nicht verfügbar")
            
            # Audit-Logging aktivieren
            if getattr(ProductionConfig, 'AUDIT_LOGGING', False):
                try:
                    from utils.audit_logger import init_audit_logging
                    init_audit_logging(app)
                    app_logger.info("[PRODUCTION] ✅ Audit-Logging aktiviert")
                except ImportError:
                    app_logger.warning("[PRODUCTION] ⚠️ Audit-Logging nicht verfügbar")
        
        # Datenbank initialisieren
        app_logger.info("[STARTUP] Initialisiere Datenbank...")
        init_database()
        app_logger.info("[STARTUP] ✅ Datenbank initialisiert")
        
        # Initial-Admin erstellen falls nicht vorhanden
        app_logger.info("[STARTUP] Prüfe Initial-Admin...")
        create_initial_admin()
        app_logger.info("[STARTUP] ✅ Admin-Benutzer geprüft")
        
        # Statische Drucker für TBA Marienfelde erstellen/aktualisieren
        app_logger.info("[STARTUP] Initialisiere statische Drucker...")
        from models import create_initial_printers
        success = create_initial_printers()
        if success:
            app_logger.info("[STARTUP] ✅ Statische Drucker konfiguriert")
        else:
            app_logger.warning("[STARTUP] ⚠️ Fehler bei Drucker-Initialisierung")
        
        # Queue Manager starten
        app_logger.info("[STARTUP] Starte Queue Manager...")
        start_queue_manager()
        app_logger.info("[STARTUP] ✅ Queue Manager gestartet")
        
        # Job Scheduler starten
        app_logger.info("[STARTUP] Starte Job Scheduler...")
        scheduler = get_job_scheduler()
        if scheduler:
            scheduler.start()
            app_logger.info("[STARTUP] ✅ Job Scheduler gestartet")
        else:
            app_logger.warning("[STARTUP] ⚠️ Job Scheduler nicht verfügbar")
        
        # SSL-Kontext für Production
        ssl_context = None
        if USE_PRODUCTION_CONFIG:
            app_logger.info("[PRODUCTION] Konfiguriere SSL...")
            try:
                from utils.ssl_suite import ssl_config
                ssl_context = ssl_config.get_ssl_context()
                app_logger.info("[PRODUCTION] ✅ SSL-Kontext konfiguriert")
            except ImportError:
                app_logger.warning("[PRODUCTION] ⚠️ SSL-Konfiguration nicht verfügbar")
        
        # Server-Konfiguration
        host = os.getenv('FLASK_HOST', '0.0.0.0')
        port = int(os.getenv('FLASK_PORT', 5000))
        
        # Production-spezifische Server-Einstellungen
        server_options = {
            'host': host,
            'port': port,
            'threaded': True
        }
        
        if USE_PRODUCTION_CONFIG:
            # Production-Server-Optimierungen
            server_options.update({
                'threaded': True,
                'processes': 1,  # Für Air-Gapped Umgebung
                'use_reloader': False,
                'use_debugger': False
            })
            
            app_logger.info(f"[PRODUCTION] 🌐 Server startet auf https://{host}:{port}")
            app_logger.info(f"[PRODUCTION] 🔧 Threaded: {server_options['threaded']}")
            app_logger.info(f"[PRODUCTION] 🔒 SSL: {'Ja' if ssl_context else 'Nein'}")
        else:
            app_logger.info(f"[STARTUP] 🌐 Server startet auf http://{host}:{port}")
        
        # Server starten
        if ssl_context:
            server_options['ssl_context'] = ssl_context
            app.run(**server_options)
        else:
            app.run(**server_options)
            
    except KeyboardInterrupt:
        app_logger.info("[SHUTDOWN] 🛑 Shutdown durch Benutzer angefordert")
    except Exception as e:
        app_logger.error(f"[ERROR] ❌ Fehler beim Starten der Anwendung: {str(e)}")
        if USE_PRODUCTION_CONFIG:
            # Production-Fehlerbehandlung
            import traceback
            app_logger.error(f"[ERROR] Traceback: {traceback.format_exc()}")
        raise
    finally:
        # Cleanup
        app_logger.info("[SHUTDOWN] 🧹 Cleanup wird ausgeführt...")
        try:
            # Queue Manager stoppen
            stop_queue_manager()
            app_logger.info("[SHUTDOWN] ✅ Queue Manager gestoppt")
            
            # Scheduler stoppen
            if 'scheduler' in locals() and scheduler:
                scheduler.shutdown()
                app_logger.info("[SHUTDOWN] ✅ Job Scheduler gestoppt")
            
            app_logger.info("[SHUTDOWN] ✅ Rate Limiter bereinigt")
            
            # Caches leeren
            clear_user_cache()
            clear_printer_status_cache()
            app_logger.info("[SHUTDOWN] ✅ Caches geleert")
            
            if USE_PRODUCTION_CONFIG:
                app_logger.info(f"[SHUTDOWN] 🏁 {ProductionConfig.COMPANY_NAME} System heruntergefahren")
            else:
                app_logger.info("[SHUTDOWN] 🏁 System heruntergefahren")
                
        except Exception as cleanup_error:
            app_logger.error(f"[SHUTDOWN] ❌ Cleanup-Fehler: {str(cleanup_error)}")

# Production-spezifische Funktionen
def get_production_info():
    """Gibt Production-Informationen zurück"""
    if USE_PRODUCTION_CONFIG:
        return {
            'company': ProductionConfig.COMPANY_NAME,
            'environment': ProductionConfig.ENVIRONMENT_NAME,
            'offline_mode': ProductionConfig.OFFLINE_MODE,
            'compliance_mode': ProductionConfig.COMPLIANCE_MODE,
            'version': '1.0.0',
            'build_date': datetime.now().strftime('%Y-%m-%d'),
            'ssl_enabled': USE_PRODUCTION_CONFIG
        }
    return None

# Template-Funktion für Production-Info
@app.template_global()
def production_info():
    """Stellt Production-Informationen für Templates bereit"""
    return get_production_info()

# Nach der Initialisierung der Blueprints und vor dem App-Start
try:
    # Admin-Berechtigungen beim Start korrigieren
    from utils.permissions import fix_all_admin_permissions
    result = fix_all_admin_permissions()
    if result['success']:
        app_logger.info(f"Admin-Berechtigungen beim Start korrigiert: {result['created']} erstellt, {result['corrected']} aktualisiert")
    else:
        app_logger.warning(f"Fehler beim Korrigieren der Admin-Berechtigungen: {result.get('error', 'Unbekannter Fehler')}")
except Exception as e:
    app_logger.error(f"Fehler beim Korrigieren der Admin-Berechtigungen beim Start: {str(e)}")

if __name__ == "__main__":
    main() 