"""
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.permissions import require_permission, Permission, check_permission
from utils.printer_monitor import printer_monitor
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("/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("/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("/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
# ============================================================================= 