"""
Drucker-Blueprint für MYP Platform
Enthält alle Routen und Funktionen zur Druckerverwaltung, Statusüberwachung und Steuerung.
"""

import os
import json
import time
from datetime import datetime, timedelta
from flask import Blueprint, request, jsonify, current_app, abort, Response
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from werkzeug.exceptions import NotFound, BadRequest
from sqlalchemy import func, desc, asc
from sqlalchemy.exc import SQLAlchemyError
from typing import Dict, List, Tuple, Any, Optional

from models import Printer, User, Job, get_db_session
from utils.logging_config import get_logger, measure_execution_time
from utils.security_suite import require_permission, Permission, check_permission
from utils.hardware_integration import printer_monitor, tapo_controller
from utils.drag_drop_system import drag_drop_manager

# Logger initialisieren
printers_logger = get_logger("printers")

# Blueprint erstellen
printers_blueprint = Blueprint("printers", __name__, url_prefix="/api/printers")

@printers_blueprint.route("", methods=["POST"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Drucker-Erstellung")
def create_printer():
    """
    Erstellt einen neuen Drucker.
    
    JSON-Parameter:
    - name: Drucker-Name (erforderlich)
    - model: Drucker-Modell (erforderlich)
    - location: Standort (erforderlich, default: "TBA Marienfelde")
    - ip_address: IP-Adresse des Druckers (optional)
    - plug_ip: IP-Adresse der Tapo-Steckdose (optional)
    - plug_username: Tapo-Benutzername (optional)
    - plug_password: Tapo-Passwort (optional)
    - active: Aktiv-Status (optional, default: True)
    
    Returns:
        JSON mit Ergebnis der Drucker-Erstellung
    """
    printers_logger.info(f"🖨️ Drucker-Erstellung von Admin {current_user.name}")
    
    # Parameter validieren
    data = request.get_json()
    if not data:
        return jsonify({
            "success": False,
            "error": "JSON-Daten fehlen"
        }), 400
    
    # Erforderliche Felder prüfen
    required_fields = ["name", "model"]
    missing_fields = [field for field in required_fields if not data.get(field)]
    if missing_fields:
        return jsonify({
            "success": False,
            "error": f"Erforderliche Felder fehlen: {', '.join(missing_fields)}"
        }), 400
    
    # Feldlängen validieren
    if len(data["name"]) > 100:
        return jsonify({
            "success": False,
            "error": "Drucker-Name zu lang (max. 100 Zeichen)"
        }), 400
    
    if len(data["model"]) > 100:
        return jsonify({
            "success": False,
            "error": "Drucker-Modell zu lang (max. 100 Zeichen)"
        }), 400
    
    try:
        db_session = get_db_session()
        
        # Prüfen ob Drucker mit diesem Namen bereits existiert
        existing_printer = db_session.query(Printer).filter(
            func.lower(Printer.name) == func.lower(data["name"])
        ).first()
        
        if existing_printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit Name '{data['name']}' existiert bereits"
            }), 409
        
        # Neuen Drucker erstellen
        new_printer = Printer(
            name=data["name"].strip(),
            model=data["model"].strip(),
            location=data.get("location", "TBA Marienfelde").strip(),
            ip_address=data.get("ip_address", "").strip() or None,
            plug_ip=data.get("plug_ip", "").strip() or None,
            plug_username=data.get("plug_username", "").strip() or None,
            plug_password=data.get("plug_password", "").strip() or None,
            active=data.get("active", True),
            status="offline",
            created_at=datetime.now(),
            last_checked=None
        )
        
        db_session.add(new_printer)
        db_session.commit()
        
        # Drucker-ID für Response speichern
        printer_id = new_printer.id
        printer_name = new_printer.name
        
        db_session.close()
        
        printers_logger.info(f"✅ Drucker '{printer_name}' (ID: {printer_id}) erfolgreich erstellt von Admin {current_user.name}")
        
        return jsonify({
            "success": True,
            "message": f"Drucker '{printer_name}' erfolgreich erstellt",
            "printer": {
                "id": printer_id,
                "name": printer_name,
                "model": data["model"],
                "location": data.get("location", "TBA Marienfelde"),
                "ip_address": data.get("ip_address"),
                "plug_ip": data.get("plug_ip"),
                "active": data.get("active", True),
                "status": "offline",
                "created_at": datetime.now().isoformat()
            },
            "created_by": {
                "id": current_user.id,
                "name": current_user.name
            },
            "timestamp": datetime.now().isoformat()
        }), 201
        
    except SQLAlchemyError as e:
        printers_logger.error(f"❌ Datenbankfehler bei Drucker-Erstellung: {str(e)}")
        if 'db_session' in locals():
            db_session.rollback()
            db_session.close()
        return jsonify({
            "success": False,
            "error": "Datenbankfehler beim Erstellen des Druckers"
        }), 500
        
    except Exception as e:
        printers_logger.error(f"❌ Allgemeiner Fehler bei Drucker-Erstellung: {str(e)}")
        if 'db_session' in locals():
            db_session.close()
        return jsonify({
            "success": False,
            "error": f"Unerwarteter Fehler: {str(e)}"
        }), 500

@printers_blueprint.route("/monitor/live-status", methods=["GET"])
@login_required
@measure_execution_time(logger=printers_logger, task_name="API-Live-Drucker-Status-Abfrage")
def get_live_printer_status():
    """
    Liefert den aktuellen Live-Status aller Drucker.
    
    Query-Parameter:
    - use_cache: ob Cache verwendet werden soll (default: true)
    
    Returns:
        JSON mit Live-Status aller Drucker
    """
    printers_logger.info(f"🔄 Live-Status-Abfrage von Benutzer {current_user.name} (ID: {current_user.id})")
    
    # Parameter auslesen
    use_cache_param = request.args.get("use_cache", "true").lower()
    use_cache = use_cache_param == "true"
    
    try:
        # Live-Status über den PrinterMonitor abrufen
        status_data = printer_monitor.get_live_printer_status(use_session_cache=use_cache)
        
        # Zusammenfassung der Druckerstatus erstellen
        summary = printer_monitor.get_printer_summary()
        
        # Antwort mit Status und Zusammenfassung
        response = {
            "success": True,
            "status": status_data,
            "summary": summary,
            "timestamp": datetime.now().isoformat(),
            "cache_used": use_cache
        }
        
        printers_logger.info(f"✅ Live-Status-Abfrage erfolgreich: {len(status_data)} Drucker")
        return jsonify(response)
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Live-Status-Abfrage: {str(e)}")
        return jsonify({
            "success": False,
            "error": "Fehler bei Abfrage des Druckerstatus",
            "message": str(e)
        }), 500

@printers_blueprint.route("/status", methods=["GET"])
@login_required
@measure_execution_time(logger=printers_logger, task_name="API-Drucker-Status-Abfrage")
def get_printer_status():
    """
    Liefert den aktuellen Status aller Drucker.
    Dieser Endpunkt ist kompatibel mit dem Frontend printer_monitor.js
    
    Query-Parameter:
    - force_refresh: true = Cache umgehen und echte Netzwerk-Tests (default: false)
    
    Returns:
        JSON mit Status aller Drucker
    """
    # Force-Refresh Parameter prüfen
    force_refresh = request.args.get('force_refresh', 'false').lower() == 'true'
    refresh_type = "Force-Refresh" if force_refresh else "Normal"
    
    printers_logger.info(f"🔄 {refresh_type} Status-Abfrage von Benutzer {current_user.name} (ID: {current_user.id})")
    
    try:
        # Nur TBA Marienfelde Drucker aus Datenbank holen
        db_session = get_db_session()
        printers = db_session.query(Printer).filter(
            Printer.location == "TBA Marienfelde"
        ).all()
        
        # Status-Daten für jeden Drucker sammeln - MIT LIVE TAPO-STATUS
        printer_data = []
        status_summary = {
            'total': len(printers),
            'available': 0,      # Erreichbar & aus → frei
            'busy': 0,           # Erreichbar & an → besetzt
            'unreachable': 0,    # Nicht erreichbar
            'unconfigured': 0,   # Keine Steckdose konfiguriert
            'error': 0
        }
        
        # Hardware Integration Monitor importieren
        try:
            from utils.hardware_integration import printer_monitor
            tapo_manager = printer_monitor
        except ImportError:
            tapo_manager = None
            printers_logger.warning("⚠️ Hardware Integration Monitor nicht verfügbar")
        
        for printer in printers:
            # Basis-Drucker-Daten
            printer_info = {
                'id': printer.id,
                'name': printer.name,
                'model': printer.model,
                'location': printer.location,
                'ip_address': printer.ip_address,
                'plug_ip': printer.plug_ip,
                'has_plug': bool(printer.plug_ip),
                'last_checked': printer.last_checked.isoformat() if printer.last_checked else None,
                'created_at': printer.created_at.isoformat() if printer.created_at else None
            }
            
            # LIVE TAPO-STATUS ABRUFEN (Kernlogik mit Force-Refresh)
            if printer.plug_ip and tapo_manager:
                try:
                    # Live-Status über Tapo-Manager abrufen (mit Cache-Bypass bei force_refresh)
                    live_status = tapo_manager.get_printer_status(printer.id, force_refresh=force_refresh)
                    
                    # Status basierend auf Tapo-Erreichbarkeit und Schaltzustand
                    plug_reachable = live_status.get('plug_reachable', False)
                    power_status = live_status.get('power_status', None)
                    
                    if not plug_reachable:
                        # Steckdose nicht erreichbar
                        printer_info['status'] = 'unreachable'
                        printer_info['status_detail'] = 'Steckdose nicht erreichbar'
                    elif power_status == 'on':
                        # Steckdose erreichbar & an → Drucker läuft
                        printer_info['status'] = 'busy'
                        printer_info['status_detail'] = 'Drucker läuft - besetzt'
                    elif power_status == 'off':
                        # Steckdose erreichbar & aus → Drucker verfügbar
                        printer_info['status'] = 'available'
                        printer_info['status_detail'] = 'Verfügbar - kann reserviert werden'
                    else:
                        # Unbekannter Status
                        printer_info['status'] = 'error'
                        printer_info['status_detail'] = 'Status unbekannt'
                    
                    # Zusätzliche Tapo-Informationen
                    printer_info['plug_reachable'] = plug_reachable
                    printer_info['power_status'] = power_status
                    printer_info['can_control'] = live_status.get('can_control', False)
                    printer_info['last_tapo_check'] = live_status.get('last_checked')
                    
                except Exception as e:
                    printers_logger.error(f"❌ Fehler bei Tapo-Status für Drucker {printer.id}: {e}")
                    printer_info['status'] = 'error'
                    printer_info['status_detail'] = f'Tapo-Fehler: {str(e)}'
                    printer_info['plug_reachable'] = False
                    printer_info['power_status'] = None
                    printer_info['can_control'] = False
            else:
                # Keine Steckdose konfiguriert oder Tapo-Manager nicht verfügbar
                printer_info['status'] = 'unconfigured'
                printer_info['status_detail'] = 'Keine Smart Plug konfiguriert'
                printer_info['plug_reachable'] = False
                printer_info['power_status'] = None
                printer_info['can_control'] = False
            
            # Status-Zusammenfassung aktualisieren
            status = printer_info['status']
            if status in status_summary:
                status_summary[status] += 1
            else:
                status_summary['error'] += 1
            
            # Aktive Jobs zählen
            active_jobs = db_session.query(Job).filter(
                Job.printer_id == printer.id,
                Job.status.in_(["running", "printing", "active", "scheduled"])
            ).count()
            
            printer_info['active_jobs'] = active_jobs
            printer_info['has_active_jobs'] = active_jobs > 0
            
            # Verfügbarkeit für Reservierung
            printer_info['can_reserve'] = (
                printer_info['status'] == 'available' and 
                active_jobs == 0 and 
                printer_info['can_control']
            )
            
            printer_data.append(printer_info)
            
            printers_logger.debug(
                f"📊 Drucker {printer.name}: Status={printer_info['status']}, "
                f"Plug-IP={printer.plug_ip}, Erreichbar={printer_info['plug_reachable']}, "
                f"Power={printer_info['power_status']}"
            )
        
        db_session.close()
        
        # Antwort mit Status und Zusammenfassung
        response = {
            "success": True,
            "printers": printer_data,
            "summary": status_summary,
            "timestamp": datetime.now().isoformat()
        }
        
        printers_logger.info(f"✅ Status-Abfrage erfolgreich: {len(printer_data)} Drucker")
        return jsonify(response)
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Status-Abfrage: {str(e)}")
        if 'db_session' in locals():
            db_session.close()
        return jsonify({
            "success": False,
            "error": "Fehler bei Abfrage des Druckerstatus",
            "message": str(e)
        }), 500

@printers_blueprint.route("/control/<int:printer_id>/power", methods=["POST"])
@login_required
@require_permission(Permission.CONTROL_PRINTER)  # Verwende die bereits vorhandene Berechtigung
@measure_execution_time(logger=printers_logger, task_name="API-Drucker-Stromversorgung-Steuerung")
def control_printer_power(printer_id):
    """
    Steuert die Stromversorgung eines Druckers (ein-/ausschalten).
    
    Args:
        printer_id: ID des zu steuernden Druckers
    
    JSON-Parameter:
    - action: "on" oder "off"
    
    Returns:
        JSON mit Ergebnis der Steuerungsaktion
    """
    printers_logger.info(f"🔌 Stromsteuerung für Drucker {printer_id} von Benutzer {current_user.name}")
    
    # Parameter validieren
    data = request.get_json()
    if not data or "action" not in data:
        return jsonify({
            "success": False,
            "error": "Parameter 'action' fehlt"
        }), 400
        
    action = data["action"]
    if action not in ["on", "off"]:
        return jsonify({
            "success": False,
            "error": "Ungültige Aktion. Erlaubt sind 'on' oder 'off'."
        }), 400
    
    try:
        # Drucker aus Datenbank holen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
            
        # Prüfen, ob Drucker eine Steckdose konfiguriert hat
        if not printer.plug_ip or not printer.plug_username or not printer.plug_password:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker {printer.name} hat keine Steckdose konfiguriert"
            }), 400
            
        # Steckdose steuern
        from PyP100 import PyP110
        try:
            # TP-Link Tapo P110 Verbindung herstellen
            p110 = PyP110.P110(printer.plug_ip, printer.plug_username, printer.plug_password)
            p110.handshake()  # Authentifizierung
            p110.login()      # Login
            
            # Steckdose ein- oder ausschalten
            if action == "on":
                p110.turnOn()
                success = True
                message = "Steckdose erfolgreich eingeschaltet"
                printer.status = "starting"  # Status aktualisieren
            else:
                p110.turnOff()
                success = True
                message = "Steckdose erfolgreich ausgeschaltet"
                printer.status = "offline"  # Status aktualisieren
                
            # Zeitpunkt der letzten Prüfung aktualisieren
            printer.last_checked = datetime.now()
            db_session.commit()
            
            # Cache leeren, damit neue Status-Abfragen aktuell sind
            printer_monitor.clear_all_caches()
            
            printers_logger.info(f"✅ {action.upper()}: Drucker {printer.name} erfolgreich {message}")
            
        except Exception as e:
            printers_logger.error(f"❌ Fehler bei Steckdosensteuerung für {printer.name}: {str(e)}")
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Fehler bei Steckdosensteuerung: {str(e)}"
            }), 500
            
        db_session.close()
        return jsonify({
            "success": True,
            "message": message,
            "printer_id": printer_id,
            "printer_name": printer.name,
            "action": action,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Allgemeiner Fehler bei Stromsteuerung: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Allgemeiner Fehler: {str(e)}"
        }), 500

@printers_blueprint.route("/force-refresh", methods=["POST"])
@login_required
@measure_execution_time(logger=printers_logger, task_name="API-Force-Refresh-Alle-Drucker")
def force_refresh_all_printer_status():
    """
    Forciert komplette Netzwerk-Neuprüfung aller Drucker-Status.
    Invalidiert alle Caches und führt echte Netzwerk-Tests durch.
    
    Für Verwendung nach Netzwerkwechseln oder bei Cache-Problemen.
    
    Returns:
        JSON mit Force-Refresh-Ergebnissen
    """
    printers_logger.info(f"🔄 Force-Refresh aller Drucker von Benutzer {current_user.name} (ID: {current_user.id})")
    
    try:
        # Hardware Integration Monitor für Force-Refresh verwenden
        from utils.hardware_integration import printer_monitor
        
        # Force-Network-Refresh durchführen
        refresh_results = printer_monitor.force_network_refresh()
        
        if refresh_results.get("success", False):
            printers_logger.info(f"✅ Force-Refresh erfolgreich: {refresh_results.get('printers_refreshed', 0)} Drucker aktualisiert")
            
            return jsonify({
                "success": True,
                "message": "Alle Drucker-Status erfolgreich aktualisiert",
                "refresh_results": refresh_results,
                "performed_by": {
                    "id": current_user.id,
                    "name": current_user.name
                },
                "timestamp": datetime.now().isoformat()
            })
        else:
            printers_logger.error(f"❌ Force-Refresh fehlgeschlagen: {refresh_results.get('error', 'Unbekannter Fehler')}")
            
            return jsonify({
                "success": False,
                "error": "Force-Refresh fehlgeschlagen",
                "details": refresh_results,
                "timestamp": datetime.now().isoformat()
            }), 500
            
    except Exception as e:
        printers_logger.error(f"❌ Allgemeiner Fehler bei Force-Refresh: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Fehler beim Force-Refresh: {str(e)}",
            "timestamp": datetime.now().isoformat()
        }), 500

@printers_blueprint.route("/test/socket/<int:printer_id>", methods=["GET"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Steckdosen-Test-Status")
def test_socket_status(printer_id):
    """
    Prüft den aktuellen Status einer Steckdose für Testzwecke (nur für Ausbilder/Administratoren).
    
    Args:
        printer_id: ID des Druckers dessen Steckdose getestet werden soll
    
    Returns:
        JSON mit detailliertem Status der Steckdose und Warnungen
    """
    printers_logger.info(f"🔍 Steckdosen-Test-Status für Drucker {printer_id} von Admin {current_user.name}")
    
    try:
        # Drucker aus Datenbank holen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
            
        # Prüfen, ob Drucker eine Steckdose konfiguriert hat
        if not printer.plug_ip or not printer.plug_username or not printer.plug_password:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker {printer.name} hat keine Steckdose konfiguriert",
                "warning": "Steckdose kann nicht getestet werden - Konfiguration fehlt"
            }), 400
            
        # Prüfen, ob der Drucker gerade aktive Jobs hat
        active_jobs = db_session.query(Job).filter(
            Job.printer_id == printer_id,
            Job.status.in_(["running", "printing", "active"])
        ).all()
        
        db_session.close()
        
        # Steckdosen-Status prüfen
        from PyP100 import PyP110
        socket_status = None
        socket_info = None
        error_message = None
        
        try:
            # TP-Link Tapo P110 Verbindung herstellen
            p110 = PyP110.P110(printer.plug_ip, printer.plug_username, printer.plug_password)
            p110.handshake()  # Authentifizierung
            p110.login()      # Login
            
            # Geräteinformationen abrufen
            device_info = p110.getDeviceInfo()
            socket_status = "online" if device_info["result"]["device_on"] else "offline"
            
            # Energieverbrauch abrufen (falls verfügbar)
            try:
                energy_info = p110.getEnergyUsage()
                current_power = energy_info.get("result", {}).get("current_power", 0)
            except:
                current_power = None
                
            socket_info = {
                "device_on": device_info["result"]["device_on"],
                "signal_level": device_info["result"].get("signal_level", 0),
                "current_power": current_power,
                "device_id": device_info["result"].get("device_id", "Unbekannt"),
                "model": device_info["result"].get("model", "Unbekannt"),
                "hw_ver": device_info["result"].get("hw_ver", "Unbekannt"),
                "fw_ver": device_info["result"].get("fw_ver", "Unbekannt")
            }
            
        except Exception as e:
            printers_logger.warning(f"⚠️ Fehler bei Steckdosen-Status-Abfrage für {printer.name}: {str(e)}")
            socket_status = "error"
            error_message = str(e)
            
        # Warnungen und Empfehlungen zusammenstellen
        warnings = []
        recommendations = []
        risk_level = "low"
        
        if active_jobs:
            warnings.append(f"ACHTUNG: Drucker hat {len(active_jobs)} aktive(n) Job(s)!")
            risk_level = "high"
            recommendations.append("Warten Sie bis alle Jobs abgeschlossen sind bevor Sie die Steckdose ausschalten")
            
        if socket_status == "online" and socket_info and socket_info.get("device_on"):
            if socket_info.get("current_power", 0) > 10:  # Mehr als 10W Verbrauch
                warnings.append(f"Drucker verbraucht aktuell {socket_info['current_power']}W - vermutlich aktiv")
                risk_level = "medium" if risk_level == "low" else risk_level
                recommendations.append("Prüfen Sie den Druckerstatus bevor Sie die Steckdose ausschalten")
            else:
                recommendations.append("Drucker scheint im Standby-Modus zu sein - Test sollte sicher möglich sein")
                
        if socket_status == "error":
            warnings.append("Steckdose nicht erreichbar - Netzwerk oder Konfigurationsproblem")
            recommendations.append("Prüfen Sie die Netzwerkverbindung und Steckdosen-Konfiguration")
            
        if not warnings and socket_status == "offline":
            recommendations.append("Steckdose ist ausgeschaltet - Test kann sicher durchgeführt werden")
        
        printers_logger.info(f"✅ Steckdosen-Test-Status erfolgreich abgerufen für {printer.name}")
        
        return jsonify({
            "success": True,
            "printer": {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model,
                "location": printer.location,
                "status": printer.status
            },
            "socket": {
                "status": socket_status,
                "info": socket_info,
                "error": error_message,
                "ip_address": printer.plug_ip
            },
            "safety": {
                "risk_level": risk_level,
                "warnings": warnings,
                "recommendations": recommendations,
                "active_jobs_count": len(active_jobs),
                "safe_to_test": len(warnings) == 0
            },
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Allgemeiner Fehler bei Steckdosen-Test-Status: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Allgemeiner Fehler: {str(e)}"
        }), 500

@printers_blueprint.route("/test/socket/<int:printer_id>/control", methods=["POST"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Steckdosen-Test-Steuerung")
def test_socket_control(printer_id):
    """
    Steuert eine Steckdose für Testzwecke (nur für Ausbilder/Administratoren).
    Diese Funktion zeigt Warnungen an, erlaubt aber trotzdem die Steuerung für Tests.
    
    Args:
        printer_id: ID des Druckers dessen Steckdose gesteuert werden soll
    
    JSON-Parameter:
    - action: "on" oder "off"
    - force: boolean - überschreibt Sicherheitswarnungen (default: false)
    - test_reason: string - Grund für den Test (optional)
    
    Returns:
        JSON mit Ergebnis der Steuerungsaktion und Warnungen
    """
    printers_logger.info(f"🧪 Steckdosen-Test-Steuerung für Drucker {printer_id} von Admin {current_user.name}")
    
    # Parameter validieren
    data = request.get_json()
    if not data or "action" not in data:
        return jsonify({
            "success": False,
            "error": "Parameter 'action' fehlt"
        }), 400
        
    action = data["action"]
    if action not in ["on", "off"]:
        return jsonify({
            "success": False,
            "error": "Ungültige Aktion. Erlaubt sind 'on' oder 'off'."
        }), 400
        
    force = data.get("force", False)
    test_reason = data.get("test_reason", "Routinetest")
    
    try:
        # Drucker aus Datenbank holen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
            
        # Prüfen, ob Drucker eine Steckdose konfiguriert hat
        if not printer.plug_ip or not printer.plug_username or not printer.plug_password:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker {printer.name} hat keine Steckdose konfiguriert"
            }), 400
            
        # Aktive Jobs prüfen
        active_jobs = db_session.query(Job).filter(
            Job.printer_id == printer_id,
            Job.status.in_(["running", "printing", "active"])
        ).all()
        
        # Sicherheitsprüfungen
        warnings = []
        should_block = False
        
        if active_jobs and action == "off":
            warnings.append(f"WARNUNG: {len(active_jobs)} aktive Job(s) würden abgebrochen!")
            if not force:
                should_block = True
                
        if should_block:
            db_session.close()
            return jsonify({
                "success": False,
                "error": "Aktion blockiert aufgrund von Sicherheitsbedenken",
                "warnings": warnings,
                "hint": "Verwenden Sie 'force': true um die Aktion trotzdem auszuführen",
                "requires_force": True
            }), 409  # Conflict
            
        # Steckdose steuern
        from PyP100 import PyP110
        try:
            # TP-Link Tapo P110 Verbindung herstellen
            p110 = PyP110.P110(printer.plug_ip, printer.plug_username, printer.plug_password)
            p110.handshake()  # Authentifizierung
            p110.login()      # Login
            
            # Aktuellen Status vor der Änderung abrufen
            device_info_before = p110.getDeviceInfo()
            status_before = device_info_before["result"]["device_on"]
            
            # Steckdose ein- oder ausschalten
            if action == "on":
                p110.turnOn()
                success = True
                message = "Steckdose für Test erfolgreich eingeschaltet"
                new_printer_status = "starting"
            else:
                p110.turnOff()
                success = True
                message = "Steckdose für Test erfolgreich ausgeschaltet"
                new_printer_status = "offline"
                
            # Kurz warten und neuen Status prüfen
            time.sleep(2)
            device_info_after = p110.getDeviceInfo()
            status_after = device_info_after["result"]["device_on"]
            
            # Drucker-Status aktualisieren
            printer.status = new_printer_status
            printer.last_checked = datetime.now()
            db_session.commit()
            
            # Cache leeren, damit neue Status-Abfragen aktuell sind
            printer_monitor.clear_all_caches()
            
            # Test-Eintrag für Audit-Log
            printers_logger.info(f"🧪 TEST DURCHGEFÜHRT: {action.upper()} für {printer.name} | "
                               f"Admin: {current_user.name} | Grund: {test_reason} | "
                               f"Force: {force} | Status: {status_before} → {status_after}")
            
        except Exception as e:
            printers_logger.error(f"❌ Fehler bei Test-Steckdosensteuerung für {printer.name}: {str(e)}")
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Fehler bei Steckdosensteuerung: {str(e)}"
            }), 500
            
        db_session.close()
        return jsonify({
            "success": True,
            "message": message,
            "test_info": {
                "admin": current_user.name,
                "reason": test_reason,
                "forced": force,
                "status_before": status_before,
                "status_after": status_after
            },
            "printer": {
                "id": printer_id,
                "name": printer.name,
                "status": new_printer_status
            },
            "action": action,
            "warnings": warnings,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Allgemeiner Fehler bei Test-Steckdosensteuerung: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Allgemeiner Fehler: {str(e)}"
        }), 500

@printers_blueprint.route("/test/all-sockets", methods=["GET"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Alle-Steckdosen-Test-Status")
def test_all_sockets_status():
    """
    Liefert den Test-Status aller konfigurierten Steckdosen (nur für Ausbilder/Administratoren).
    
    Returns:
        JSON mit Status aller Steckdosen und Gesamtübersicht
    """
    printers_logger.info(f"🔍 Alle-Steckdosen-Test-Status von Admin {current_user.name}")
    
    try:
        # Alle Drucker mit Steckdosen-Konfiguration holen
        db_session = get_db_session()
        printers = db_session.query(Printer).filter(
            Printer.plug_ip.isnot(None),
            Printer.plug_username.isnot(None),
            Printer.plug_password.isnot(None)
        ).all()
        
        results = []
        total_online = 0
        total_offline = 0
        total_error = 0
        total_warnings = 0
        
        from PyP100 import PyP110
        
        for printer in printers:
            # Aktive Jobs für diesen Drucker prüfen
            active_jobs = db_session.query(Job).filter(
                Job.printer_id == printer.id,
                Job.status.in_(["running", "printing", "active"])
            ).count()
            
            # Steckdosen-Status prüfen
            socket_status = "unknown"
            device_on = False
            current_power = None
            error_message = None
            warnings = []
            
            try:
                p110 = PyP110.P110(printer.plug_ip, printer.plug_username, printer.plug_password)
                p110.handshake()
                p110.login()
                
                device_info = p110.getDeviceInfo()
                device_on = device_info["result"]["device_on"]
                socket_status = "online" if device_on else "offline"
                
                # Energieverbrauch abrufen
                try:
                    energy_info = p110.getEnergyUsage()
                    current_power = energy_info.get("result", {}).get("current_power", 0)
                except:
                    current_power = None
                    
                # Warnungen generieren
                if active_jobs > 0:
                    warnings.append(f"{active_jobs} aktive Job(s)")
                    
                if device_on and current_power and current_power > 10:
                    warnings.append(f"Hoher Verbrauch: {current_power}W")
                    
            except Exception as e:
                socket_status = "error"
                error_message = str(e)
                warnings.append(f"Verbindungsfehler: {str(e)[:50]}")
                
            # Statistiken aktualisieren
            if socket_status == "online":
                total_online += 1
            elif socket_status == "offline":
                total_offline += 1
            else:
                total_error += 1
                
            if warnings:
                total_warnings += 1
                
            results.append({
                "printer": {
                    "id": printer.id,
                    "name": printer.name,
                    "model": printer.model,
                    "location": printer.location
                },
                "socket": {
                    "status": socket_status,
                    "device_on": device_on,
                    "current_power": current_power,
                    "ip_address": printer.plug_ip,
                    "error": error_message
                },
                "warnings": warnings,
                "active_jobs": active_jobs,
                "safe_to_test": len(warnings) == 0
            })
            
        db_session.close()
        
        # Gesamtübersicht erstellen
        summary = {
            "total_sockets": len(results),
            "online": total_online,
            "offline": total_offline,
            "error": total_error,
            "with_warnings": total_warnings,
            "safe_to_test": len(results) - total_warnings
        }
        
        printers_logger.info(f"✅ Alle-Steckdosen-Status erfolgreich abgerufen: {len(results)} Steckdosen")
        
        return jsonify({
            "success": True,
            "sockets": results,
            "summary": summary,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Alle-Steckdosen-Test-Status: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Allgemeiner Fehler: {str(e)}"
        }), 500


# =============================================================================
# DRAG & DROP API - JOB-REIHENFOLGE-MANAGEMENT
# =============================================================================

@printers_blueprint.route("/<int:printer_id>/jobs/order", methods=["GET"])
@login_required
@measure_execution_time(logger=printers_logger, task_name="API-Job-Reihenfolge-Abfrage")
def get_job_order(printer_id):
    """
    Holt die aktuelle Job-Reihenfolge für einen Drucker.
    
    Args:
        printer_id: ID des Druckers
    
    Returns:
        JSON mit Jobs in der korrekten Reihenfolge
    """
    printers_logger.info(f"📋 Job-Reihenfolge-Abfrage für Drucker {printer_id} von Benutzer {current_user.name}")
    
    try:
        # Drucker existiert prüfen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
        
        db_session.close()
        
        # Job-Reihenfolge und Details holen
        ordered_jobs = drag_drop_manager.get_ordered_jobs_for_printer(printer_id)
        job_order_ids = drag_drop_manager.get_job_order(printer_id)
        
        # Job-Details für Response aufbereiten
        jobs_data = []
        for job in ordered_jobs:
            jobs_data.append({
                "id": job.id,
                "name": job.name,
                "description": job.description,
                "user_name": job.user.name if job.user else "Unbekannt",
                "user_id": job.user_id,
                "duration_minutes": job.duration_minutes,
                "created_at": job.created_at.isoformat() if job.created_at else None,
                "start_at": job.start_at.isoformat() if job.start_at else None,
                "status": job.status,
                "file_path": job.file_path
            })
        
        printers_logger.info(f"✅ Job-Reihenfolge erfolgreich abgerufen: {len(jobs_data)} Jobs für Drucker {printer.name}")
        
        return jsonify({
            "success": True,
            "printer": {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model,
                "location": printer.location
            },
            "jobs": jobs_data,
            "job_order": job_order_ids,
            "total_jobs": len(jobs_data),
            "total_duration_minutes": sum(job.duration_minutes for job in ordered_jobs),
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Job-Reihenfolge-Abfrage für Drucker {printer_id}: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Fehler beim Laden der Job-Reihenfolge: {str(e)}"
        }), 500

@printers_blueprint.route("/<int:printer_id>/jobs/order", methods=["POST"])
@login_required
@require_permission(Permission.APPROVE_JOBS)  # Nur Benutzer mit Job-Genehmigungsrechten können Reihenfolge ändern
@measure_execution_time(logger=printers_logger, task_name="API-Job-Reihenfolge-Update")
def update_job_order(printer_id):
    """
    Aktualisiert die Job-Reihenfolge für einen Drucker per Drag & Drop.
    
    Args:
        printer_id: ID des Druckers
    
    JSON-Parameter:
    - job_ids: Liste der Job-IDs in der gewünschten Reihenfolge
    
    Returns:
        JSON mit Bestätigung der Aktualisierung
    """
    printers_logger.info(f"🔄 Job-Reihenfolge-Update für Drucker {printer_id} von Benutzer {current_user.name}")
    
    # Parameter validieren
    data = request.get_json()
    if not data or "job_ids" not in data:
        return jsonify({
            "success": False,
            "error": "Parameter 'job_ids' fehlt"
        }), 400
    
    job_ids = data["job_ids"]
    if not isinstance(job_ids, list):
        return jsonify({
            "success": False,
            "error": "Parameter 'job_ids' muss eine Liste sein"
        }), 400
    
    if not all(isinstance(job_id, int) for job_id in job_ids):
        return jsonify({
            "success": False,
            "error": "Alle Job-IDs müssen Zahlen sein"
        }), 400
    
    try:
        # Drucker existiert prüfen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
        
        # Validierung: Alle Jobs gehören zum Drucker und sind editierbar
        valid_jobs = db_session.query(Job).filter(
            Job.id.in_(job_ids),
            Job.printer_id == printer_id,
            Job.status.in_(['scheduled', 'paused'])
        ).all()
        
        db_session.close()
        
        if len(valid_jobs) != len(job_ids):
            invalid_ids = set(job_ids) - {job.id for job in valid_jobs}
            return jsonify({
                "success": False,
                "error": f"Ungültige oder nicht editierbare Job-IDs: {list(invalid_ids)}"
            }), 400
        
        # Berechtigung prüfen: Benutzer kann nur eigene Jobs oder als Admin alle verschieben
        if not current_user.is_admin:
            user_job_ids = {job.id for job in valid_jobs if job.user_id == current_user.id}
            if user_job_ids != set(job_ids):
                unauthorized_ids = set(job_ids) - user_job_ids
                return jsonify({
                    "success": False,
                    "error": f"Keine Berechtigung für Jobs: {list(unauthorized_ids)}"
                }), 403
        
        # Job-Reihenfolge aktualisieren
        success = drag_drop_manager.update_job_order(printer_id, job_ids)
        
        if success:
            # Neue Reihenfolge zur Bestätigung laden
            updated_order = drag_drop_manager.get_job_order(printer_id)
            
            printers_logger.info(f"✅ Job-Reihenfolge erfolgreich aktualisiert für Drucker {printer.name}")
            printers_logger.info(f"   Neue Reihenfolge: {job_ids}")
            printers_logger.info(f"   Benutzer: {current_user.name} (ID: {current_user.id})")
            
            return jsonify({
                "success": True,
                "message": "Job-Reihenfolge erfolgreich aktualisiert",
                "printer": {
                    "id": printer.id,
                    "name": printer.name
                },
                "old_order": job_ids,  # Eingabe des Benutzers
                "new_order": updated_order,  # Bestätigung aus Datenbank
                "total_jobs": len(job_ids),
                "updated_by": {
                    "id": current_user.id,
                    "name": current_user.name
                },
                "timestamp": datetime.now().isoformat()
            })
        else:
            return jsonify({
                "success": False,
                "error": "Fehler beim Speichern der Job-Reihenfolge"
            }), 500
            
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Job-Reihenfolge-Update für Drucker {printer_id}: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Unerwarteter Fehler: {str(e)}"
        }), 500

@printers_blueprint.route("/<int:printer_id>/jobs/summary", methods=["GET"])
@login_required
@measure_execution_time(logger=printers_logger, task_name="API-Drucker-Job-Zusammenfassung")
def get_printer_job_summary(printer_id):
    """
    Erstellt eine detaillierte Zusammenfassung der Jobs für einen Drucker.
    
    Args:
        printer_id: ID des Druckers
    
    Returns:
        JSON mit Zusammenfassung, Statistiken und Zeitschätzungen
    """
    printers_logger.info(f"📊 Drucker-Job-Zusammenfassung für Drucker {printer_id} von Benutzer {current_user.name}")
    
    try:
        # Drucker existiert prüfen
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Drucker mit ID {printer_id} nicht gefunden"
            }), 404
        
        db_session.close()
        
        # Zusammenfassung über Drag-Drop-Manager erstellen
        summary = drag_drop_manager.get_printer_summary(printer_id)
        
        printers_logger.info(f"✅ Drucker-Job-Zusammenfassung erfolgreich erstellt für {printer.name}")
        
        return jsonify({
            "success": True,
            "printer": {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model,
                "location": printer.location,
                "status": printer.status
            },
            "summary": summary,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Drucker-Job-Zusammenfassung für Drucker {printer_id}: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Fehler beim Erstellen der Zusammenfassung: {str(e)}"
        }), 500

@printers_blueprint.route("/jobs/cleanup-orders", methods=["POST"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Job-Reihenfolgen-Bereinigung")
def cleanup_job_orders():
    """
    Bereinigt ungültige Job-Reihenfolgen (nur für Administratoren).
    Entfernt Einträge für abgeschlossene oder gelöschte Jobs.
    
    Returns:
        JSON mit Bereinigungsergebnis
    """
    printers_logger.info(f"🧹 Job-Reihenfolgen-Bereinigung von Admin {current_user.name}")
    
    try:
        # Bereinigung durchführen
        drag_drop_manager.cleanup_invalid_orders()
        
        printers_logger.info(f"✅ Job-Reihenfolgen-Bereinigung erfolgreich abgeschlossen")
        
        return jsonify({
            "success": True,
            "message": "Job-Reihenfolgen erfolgreich bereinigt",
            "admin": {
                "id": current_user.id,
                "name": current_user.name
            },
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Job-Reihenfolgen-Bereinigung: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Fehler bei der Bereinigung: {str(e)}"
        }), 500

@printers_blueprint.route("/drag-drop/config", methods=["GET"])
@login_required
def get_drag_drop_config():
    """
    Liefert die Konfiguration für das Drag & Drop System.
    
    Returns:
        JSON mit Drag & Drop Konfiguration und JavaScript/CSS
    """
    printers_logger.info(f"⚙️ Drag-Drop-Konfiguration abgerufen von Benutzer {current_user.name}")
    
    try:
        from utils.drag_drop_system import get_drag_drop_javascript, get_drag_drop_css
        
        # Benutzerberechtigungen prüfen
        can_reorder_jobs = check_permission(current_user, Permission.APPROVE_JOBS)
        can_upload_files = check_permission(current_user, Permission.CREATE_JOB)
        
        config = {
            "permissions": {
                "can_reorder_jobs": can_reorder_jobs,
                "can_upload_files": can_upload_files,
                "is_admin": current_user.is_admin
            },
            "settings": {
                "max_file_size": 50 * 1024 * 1024,  # 50MB
                "accepted_file_types": ["gcode", "stl", "3mf", "obj"],
                "auto_upload": False,
                "show_preview": True,
                "enable_progress_tracking": True
            },
            "endpoints": {
                "get_job_order": f"/api/printers/{{printer_id}}/jobs/order",
                "update_job_order": f"/api/printers/{{printer_id}}/jobs/order",
                "get_summary": f"/api/printers/{{printer_id}}/jobs/summary"
            },
            "javascript": get_drag_drop_javascript(),
            "css": get_drag_drop_css()
        }
        
        return jsonify({
            "success": True,
            "config": config,
            "user": {
                "id": current_user.id,
                "name": current_user.name,
                "role": current_user.role
            },
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Drag-Drop-Konfiguration: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Fehler beim Laden der Konfiguration: {str(e)}"
        }), 500

# =============================================================================
# ENDE DRAG & DROP API
# =============================================================================

@printers_blueprint.route("/tapo/status-check", methods=["POST"])
@login_required
@require_permission(Permission.CONTROL_PRINTER)
@measure_execution_time(logger=printers_logger, task_name="API-Massenhafte-Tapo-Status-Prüfung")
def mass_tapo_status_check():
    """
    Führt eine vollständige Tapo-Status-Überprüfung für alle Drucker durch.
    
    Returns:
        JSON mit detailliertem Status aller Tapo-Steckdosen
    """
    printers_logger.info(f"Massenhafte Tapo-Status-Prüfung von Benutzer {current_user.name}")
    
    try:
        db_session = get_db_session()
        
        # Alle Drucker laden
        all_printers = db_session.query(Printer).all()
        
        # Tapo-Controller laden
        try:
            from utils.hardware_integration import tapo_controller
            tapo_available = True
        except Exception as e:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Tapo-Controller nicht verfügbar: {str(e)}",
                "tapo_available": False
            }), 500
        
        printer_status = []
        summary = {
            "total_printers": len(all_printers),
            "printers_with_tapo": 0,
            "printers_without_tapo": 0,
            "tapo_online": 0,
            "tapo_offline": 0,
            "tapo_unreachable": 0,
            "configuration_issues": 0
        }
        
        for printer in all_printers:
            printer_info = {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model,
                "location": printer.location,
                "active": printer.active,
                "has_tapo_config": bool(printer.plug_ip),
                "plug_ip": printer.plug_ip,
                "last_checked": datetime.now()
            }
            
            if not printer.plug_ip:
                # Drucker ohne Tapo-Konfiguration
                summary["printers_without_tapo"] += 1
                printer_info.update({
                    "tapo_status": "not_configured",
                    "tapo_reachable": False,
                    "power_status": None,
                    "recommendations": ["Tapo-Steckdose konfigurieren für automatische Steuerung"]
                })
            else:
                # Drucker mit Tapo-Konfiguration
                summary["printers_with_tapo"] += 1
                
                # Konfigurationsprüfung
                config_issues = []
                if not printer.plug_username:
                    config_issues.append("Tapo-Benutzername fehlt")
                if not printer.plug_password:
                    config_issues.append("Tapo-Passwort fehlt")
                
                if config_issues:
                    summary["configuration_issues"] += 1
                    printer_info.update({
                        "tapo_status": "configuration_error",
                        "tapo_reachable": False,
                        "power_status": None,
                        "config_issues": config_issues,
                        "recommendations": ["Tapo-Anmeldedaten vervollständigen"]
                    })
                else:
                    # Vollständige Konfiguration - Status prüfen
                    try:
                        reachable, status = tapo_controller.check_outlet_status(
                            printer.plug_ip,
                            printer_id=printer.id
                        )
                        
                        if reachable:
                            if status == "on":
                                summary["tapo_online"] += 1
                                status_type = "online"
                                recommendations = []
                            else:
                                summary["tapo_offline"] += 1
                                status_type = "offline"
                                recommendations = ["Steckdose kann bei Bedarf eingeschaltet werden"]
                        else:
                            summary["tapo_unreachable"] += 1
                            status_type = "unreachable"
                            recommendations = ["Netzwerkverbindung prüfen", "IP-Adresse überprüfen"]
                        
                        printer_info.update({
                            "tapo_status": status_type,
                            "tapo_reachable": reachable,
                            "power_status": status,
                            "recommendations": recommendations
                        })
                        
                        # Drucker-Status in DB aktualisieren
                        if reachable:
                            printer.last_checked = datetime.now()
                            if status == "on":
                                printer.status = "online"
                            else:
                                printer.status = "offline"
                        else:
                            printer.status = "unreachable"
                        
                    except Exception as tapo_error:
                        summary["tapo_unreachable"] += 1
                        printer_info.update({
                            "tapo_status": "error",
                            "tapo_reachable": False,
                            "power_status": None,
                            "error": str(tapo_error),
                            "recommendations": ["Tapo-Verbindung prüfen", "Anmeldedaten überprüfen"]
                        })
                        printers_logger.warning(f"Tapo-Fehler für {printer.name}: {str(tapo_error)}")
            
            # Aktuelle Jobs für zusätzliche Info
            active_jobs = db_session.query(Job).filter(
                Job.printer_id == printer.id,
                Job.status.in_(["running", "printing", "active", "scheduled"])
            ).count()
            
            printer_info["active_jobs"] = active_jobs
            if active_jobs > 0:
                printer_info.setdefault("recommendations", []).append(
                    f"Vorsicht: {active_jobs} aktive Job(s) bei Steckdosen-Änderungen"
                )
            
            printer_status.append(printer_info)
        
        # Änderungen in DB speichern
        db_session.commit()
        db_session.close()
        
        # Übersicht der Ergebnisse
        coverage_percentage = (summary["printers_with_tapo"] / summary["total_printers"] * 100) if summary["total_printers"] > 0 else 0
        health_score = ((summary["tapo_online"] + summary["tapo_offline"]) / summary["printers_with_tapo"] * 100) if summary["printers_with_tapo"] > 0 else 0
        
        printers_logger.info(f"Tapo-Status-Check abgeschlossen: {summary['printers_with_tapo']} konfiguriert, "
                           f"{summary['tapo_online']} online, {summary['tapo_unreachable']} nicht erreichbar")
        
        return jsonify({
            "success": True,
            "tapo_available": tapo_available,
            "printers": printer_status,
            "summary": summary,
            "metrics": {
                "coverage_percentage": round(coverage_percentage, 1),
                "health_score": round(health_score, 1),
                "needs_attention": summary["configuration_issues"] + summary["tapo_unreachable"]
            },
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"Unerwarteter Fehler bei Massenhafte-Tapo-Status-Prüfung: {str(e)}")
        if 'db_session' in locals():
            db_session.close()
        return jsonify({
            "success": False,
            "error": f"Systemfehler: {str(e)}"
        }), 500

@printers_blueprint.route("/tapo/configuration-wizard", methods=["POST"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Tapo-Konfigurationsassistent")
def tapo_configuration_wizard():
    """
    Automatischer Konfigurationsassistent für Tapo-Steckdosen.
    Versucht automatisch verfügbare Steckdosen zu erkennen und zu konfigurieren.
    """
    printers_logger.info(f"Tapo-Konfigurationsassistent von Admin {current_user.name}")
    
    try:
        data = request.get_json()
        auto_configure = data.get('auto_configure', True)
        test_ips = data.get('test_ips', [])
        
        # Tapo-Controller laden
        try:
            from utils.hardware_integration import tapo_controller
        except Exception as e:
            return jsonify({
                "success": False,
                "error": f"Tapo-Controller nicht verfügbar: {str(e)}"
            }), 500
        
        db_session = get_db_session()
        
        # Standard-IP-Bereich für Mercedes-Benz TBA (normalerweise 192.168.1.201-206)
        if not test_ips:
            test_ips = [f"192.168.1.{i}" for i in range(201, 207)]  # 6 Standard-Arbeitsplätze
        
        discovery_results = {
            "tested_ips": test_ips,
            "discovered_devices": [],
            "configured_printers": [],
            "errors": []
        }
        
        printers_logger.info(f"Teste {len(test_ips)} IP-Adressen auf Tapo-Geräte...")
        
        # Discovery für jede IP-Adresse
        for ip in test_ips:
            try:
                printers_logger.debug(f"Teste IP: {ip}")
                
                # Ping-Test mit 5 Sekunden Timeout
                if not tapo_controller.ping_address(ip, timeout=5):
                    discovery_results["errors"].append(f"{ip}: Nicht erreichbar (Ping fehlgeschlagen)")
                    continue
                
                # Tapo-Verbindungstest
                test_result = tapo_controller.test_connection(ip)
                
                if test_result["success"]:
                    device_info = test_result.get("device_info", {})
                    
                    discovered_device = {
                        "ip": ip,
                        "device_info": device_info,
                        "nickname": device_info.get("nickname", f"Tapo Device {ip}"),
                        "model": device_info.get("model", "Unknown"),
                        "device_on": device_info.get("device_on", False)
                    }
                    
                    discovery_results["discovered_devices"].append(discovered_device)
                    printers_logger.info(f"✅ Tapo-Gerät gefunden: {ip} - {discovered_device['nickname']}")
                    
                    # Auto-Konfiguration wenn gewünscht
                    if auto_configure:
                        # Suche nach Drucker ohne Tapo-Konfiguration
                        unconfigured_printer = db_session.query(Printer).filter(
                            Printer.plug_ip.is_(None),
                            Printer.active == True
                        ).first()
                        
                        if unconfigured_printer:
                            # Konfiguriere den ersten verfügbaren Drucker
                            unconfigured_printer.plug_ip = ip
                            unconfigured_printer.plug_username = "admin"  # Standard für Tapo
                            unconfigured_printer.plug_password = "admin"  # Standard für Tapo
                            unconfigured_printer.last_checked = datetime.now()
                            
                            configured_info = {
                                "printer_id": unconfigured_printer.id,
                                "printer_name": unconfigured_printer.name,
                                "tapo_ip": ip,
                                "tapo_nickname": discovered_device['nickname']
                            }
                            
                            discovery_results["configured_printers"].append(configured_info)
                            printers_logger.info(f"✅ Drucker '{unconfigured_printer.name}' automatisch mit {ip} verknüpft")
                        else:
                            discovery_results["errors"].append(f"{ip}: Tapo-Gerät gefunden, aber kein unkonfigurierter Drucker verfügbar")
                    
                else:
                    discovery_results["errors"].append(f"{ip}: Erreichbar, aber kein Tapo-Gerät oder Authentifizierung fehlgeschlagen")
                
            except Exception as ip_error:
                discovery_results["errors"].append(f"{ip}: Fehler beim Test - {str(ip_error)}")
                printers_logger.warning(f"Fehler beim Testen von {ip}: {str(ip_error)}")
        
        # Änderungen speichern
        db_session.commit()
        db_session.close()
        
        # Zusammenfassung
        summary = {
            "tested_ips": len(test_ips),
            "discovered_devices": len(discovery_results["discovered_devices"]),
            "configured_printers": len(discovery_results["configured_printers"]),
            "errors": len(discovery_results["errors"])
        }
        
        printers_logger.info(f"Tapo-Konfigurationsassistent abgeschlossen: {summary}")
        
        return jsonify({
            "success": True,
            "message": f"Discovery abgeschlossen: {summary['discovered_devices']} Geräte gefunden, "
                      f"{summary['configured_printers']} Drucker konfiguriert",
            "results": discovery_results,
            "summary": summary,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"Fehler beim Tapo-Konfigurationsassistent: {str(e)}")
        if 'db_session' in locals():
            db_session.close()
        return jsonify({
            "success": False,
            "error": f"Systemfehler: {str(e)}"
        }), 500

@printers_blueprint.route("/<int:printer_id>/connect", methods=["POST"])
@login_required
@require_permission(Permission.CONTROL_PRINTER)
@measure_execution_time(logger=printers_logger, task_name="API-Drucker-Verbindung")
def connect_printer(printer_id):
    """
    Verbindet einen Drucker (schaltet die Steckdose ein).
    Wrapper für control_printer_power mit action='on'
    
    Args:
        printer_id: ID des zu verbindenden Druckers
    
    Returns:
        JSON mit Ergebnis der Verbindungsaktion
    """
    printers_logger.info(f"🔗 Drucker-Verbindung für Drucker {printer_id} von Benutzer {current_user.name}")
    
    try:
        # Sichere JSON-Handhabung für control_printer_power
        try:
            original_json = request.get_json(silent=True)
        except:
            original_json = None
        request._cached_json = ({"action": "on"}, True)
        
        # Delegiere an existing control_printer_power function
        result = control_printer_power(printer_id)
        
        # Response für connect-API anpassen
        if hasattr(result, 'get_json') and result.get_json().get('success'):
            data = result.get_json()
            return jsonify({
                "success": True,
                "message": f"Verbindung zu Drucker {printer_id} hergestellt",
                "printer_id": printer_id,
                "printer_name": data.get('printer_name'),
                "action": "connect",
                "timestamp": data.get('timestamp')
            })
        
        return result
        
    except Exception as e:
        printers_logger.error(f"❌ Fehler bei Drucker-Verbindung: {str(e)}")
        return jsonify({
            "success": False,
            "error": f"Verbindungsfehler: {str(e)}"
        }), 500

@printers_blueprint.route("/tapo/validate-configuration/<int:printer_id>", methods=["POST"])
@login_required
@require_permission(Permission.ADMIN)
@measure_execution_time(logger=printers_logger, task_name="API-Tapo-Konfigurationsvalidierung")
def validate_tapo_configuration(printer_id):
    """
    Validiert die Tapo-Konfiguration eines spezifischen Druckers.
    Führt umfassende Tests durch: Ping, Authentifizierung, Funktionalität.
    """
    printers_logger.info(f"Tapo-Konfigurationsvalidierung für Drucker {printer_id} von Admin {current_user.name}")
    
    try:
        db_session = get_db_session()
        printer = db_session.query(Printer).filter(Printer.id == printer_id).first()
        
        if not printer:
            db_session.close()
            return jsonify({
                "success": False,
                "error": "Drucker nicht gefunden"
            }), 404
        
        # Tapo-Controller laden
        try:
            from utils.hardware_integration import tapo_controller
        except Exception as e:
            db_session.close()
            return jsonify({
                "success": False,
                "error": f"Tapo-Controller nicht verfügbar: {str(e)}"
            }), 500
        
        validation_results = {
            "printer": {
                "id": printer.id,
                "name": printer.name,
                "model": printer.model,
                "location": printer.location
            },
            "configuration": {
                "has_ip": bool(printer.plug_ip),
                "has_username": bool(printer.plug_username),
                "has_password": bool(printer.plug_password),
                "ip_address": printer.plug_ip
            },
            "tests": {
                "ping": {"status": "not_run", "message": ""},
                "authentication": {"status": "not_run", "message": ""},
                "functionality": {"status": "not_run", "message": ""},
                "device_info": {"status": "not_run", "message": ""}
            },
            "overall_status": "unknown",
            "recommendations": []
        }
        
        # Konfigurationsprüfung
        if not printer.plug_ip:
            validation_results["overall_status"] = "not_configured"
            validation_results["recommendations"].append("IP-Adresse der Tapo-Steckdose eintragen")
        elif not printer.plug_username or not printer.plug_password:
            validation_results["overall_status"] = "incomplete_config"
            validation_results["recommendations"].append("Benutzername und Passwort für Tapo-Steckdose eintragen")
        else:
            # Umfassende Tests durchführen
            all_tests_passed = True
            
            # Test 1: Ping/Erreichbarkeit
            try:
                ping_success = tapo_controller.ping_address(printer.plug_ip, timeout=5)
                if ping_success:
                    validation_results["tests"]["ping"] = {
                        "status": "passed",
                        "message": "Steckdose ist im Netzwerk erreichbar"
                    }
                else:
                    validation_results["tests"]["ping"] = {
                        "status": "failed",
                        "message": "Steckdose nicht erreichbar - Netzwerkproblem oder falsche IP"
                    }
                    all_tests_passed = False
                    validation_results["recommendations"].append("IP-Adresse überprüfen")
                    validation_results["recommendations"].append("Netzwerkverbindung der Steckdose prüfen")
            except Exception as ping_error:
                validation_results["tests"]["ping"] = {
                    "status": "error",
                    "message": f"Ping-Test fehlgeschlagen: {str(ping_error)}"
                }
                all_tests_passed = False
            
            # Test 2: Authentifizierung (nur wenn Ping erfolgreich)
            if validation_results["tests"]["ping"]["status"] == "passed":
                try:
                    auth_result = tapo_controller.test_connection(
                        printer.plug_ip,
                        username=printer.plug_username,
                        password=printer.plug_password
                    )
                    
                    if auth_result["success"]:
                        validation_results["tests"]["authentication"] = {
                            "status": "passed",
                            "message": "Authentifizierung erfolgreich"
                        }
                        
                        # Geräteinformationen extrahieren
                        device_info = auth_result.get("device_info", {})
                        validation_results["tests"]["device_info"] = {
                            "status": "passed",
                            "message": "Geräteinformationen abgerufen",
                            "data": {
                                "nickname": device_info.get("nickname", "Unbekannt"),
                                "model": device_info.get("model", "Unbekannt"),
                                "device_on": device_info.get("device_on", False),
                                "signal_level": device_info.get("signal_level", 0)
                            }
                        }
                    else:
                        validation_results["tests"]["authentication"] = {
                            "status": "failed",
                            "message": f"Authentifizierung fehlgeschlagen: {auth_result.get('error', 'Unbekannt')}"
                        }
                        all_tests_passed = False
                        validation_results["recommendations"].append("Benutzername und Passwort überprüfen")
                        
                except Exception as auth_error:
                    validation_results["tests"]["authentication"] = {
                        "status": "error",
                        "message": f"Authentifizierungstest fehlgeschlagen: {str(auth_error)}"
                    }
                    all_tests_passed = False
            
            # Test 3: Funktionalität (nur wenn Authentifizierung erfolgreich)
            if validation_results["tests"]["authentication"]["status"] == "passed":
                try:
                    reachable, status = tapo_controller.check_outlet_status(
                        printer.plug_ip,
                        printer_id=printer_id
                    )
                    
                    if reachable:
                        validation_results["tests"]["functionality"] = {
                            "status": "passed",
                            "message": f"Status erfolgreich abgerufen: {status}",
                            "current_status": status
                        }
                        
                        # Drucker-Status in DB aktualisieren
                        printer.last_checked = datetime.now()
                        printer.status = "online" if status == "on" else "offline"
                        
                    else:
                        validation_results["tests"]["functionality"] = {
                            "status": "failed",
                            "message": "Status konnte nicht abgerufen werden"
                        }
                        all_tests_passed = False
                        
                except Exception as func_error:
                    validation_results["tests"]["functionality"] = {
                        "status": "error",
                        "message": f"Funktionalitätstest fehlgeschlagen: {str(func_error)}"
                    }
                    all_tests_passed = False
            
            # Gesamtstatus bestimmen
            if all_tests_passed:
                validation_results["overall_status"] = "fully_functional"
                validation_results["recommendations"].append("Konfiguration ist vollständig und funktional")
            else:
                failed_tests = [test for test, result in validation_results["tests"].items() 
                              if result["status"] in ["failed", "error"]]
                
                if "ping" in failed_tests:
                    validation_results["overall_status"] = "network_issue"
                elif "authentication" in failed_tests:
                    validation_results["overall_status"] = "auth_issue"
                elif "functionality" in failed_tests:
                    validation_results["overall_status"] = "functionality_issue"
                else:
                    validation_results["overall_status"] = "partial_failure"
        
        # Aktuelle Jobs als Sicherheitshinweis
        active_jobs = db_session.query(Job).filter(
            Job.printer_id == printer_id,
            Job.status.in_(["running", "printing", "active"])
        ).count()
        
        if active_jobs > 0:
            validation_results["safety_warning"] = f"{active_jobs} aktive Job(s) - Vorsicht bei Steckdosen-Tests"
        
        db_session.commit()
        db_session.close()
        
        printers_logger.info(f"Tapo-Validierung für {printer.name} abgeschlossen: {validation_results['overall_status']}")
        
        return jsonify({
            "success": True,
            "validation": validation_results,
            "timestamp": datetime.now().isoformat()
        })
        
    except Exception as e:
        printers_logger.error(f"Fehler bei Tapo-Konfigurationsvalidierung: {str(e)}")
        if 'db_session' in locals():
            db_session.close()
        return jsonify({
            "success": False,
            "error": f"Systemfehler: {str(e)}"
        }), 500 