"""
Benutzer-Blueprint für das 3D-Druck-Management-System

Dieses Modul enthält alle Benutzer-spezifischen Routen und Funktionen,
einschließlich Profilverwaltung, Einstellungen und Passwort-Änderung.
"""

import json
from datetime import datetime
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash, make_response
from flask_login import login_required, current_user
from werkzeug.security import check_password_hash
from models import User, get_db_session
from utils.logging_config import get_logger

# Blueprint erstellen
user_blueprint = Blueprint('user', __name__, url_prefix='/user')

# Logger initialisieren
user_logger = get_logger("user")

@user_blueprint.route("/profile", methods=["GET"])
@login_required
def profile():
    """Benutzerprofil anzeigen"""
    return render_template('user/profile.html', user=current_user)

@user_blueprint.route("/settings", methods=["GET"])
@login_required
def settings():
    """Benutzereinstellungen anzeigen"""
    return render_template('user/settings.html', user=current_user)

@user_blueprint.route("/update-profile", methods=["POST"])
@login_required
def update_profile():
    """Benutzerprofil aktualisieren (Form-basiert)"""
    try:
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            flash("Benutzer nicht gefunden", "error")
            return redirect(url_for('user.profile'))
        
        # Aktualisierbare Felder aus dem Formular
        user.name = request.form.get('name', user.name)
        user.email = request.form.get('email', user.email)
        user.department = request.form.get('department', user.department)
        user.position = request.form.get('position', user.position)
        user.phone = request.form.get('phone', user.phone)
        user.bio = request.form.get('bio', user.bio)
        
        user.updated_at = datetime.now()
        db_session.commit()
        
        user_logger.info(f"Profil aktualisiert für Benutzer {user.username}")
        flash("Profil erfolgreich aktualisiert", "success")
        
        db_session.close()
        return redirect(url_for('user.profile'))
        
    except Exception as e:
        user_logger.error(f"Fehler beim Aktualisieren des Profils: {str(e)}")
        flash("Fehler beim Aktualisieren des Profils", "error")
        return redirect(url_for('user.profile'))

@user_blueprint.route("/api/update-settings", methods=["POST"])
@login_required
def api_update_settings():
    """API-Endpunkt für Einstellungen-Updates"""
    try:
        data = request.get_json()
        
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            return jsonify({"error": "Benutzer nicht gefunden"}), 404
        
        # Einstellungen JSON aktualisieren
        current_settings = user.settings or {}
        if isinstance(current_settings, str):
            try:
                current_settings = json.loads(current_settings)
            except json.JSONDecodeError:
                current_settings = {}
        
        # Neue Einstellungen hinzufügen/aktualisieren
        for key, value in data.items():
            current_settings[key] = value
        
        user.settings = json.dumps(current_settings)
        user.updated_at = datetime.now()
        db_session.commit()
        
        user_logger.info(f"Einstellungen aktualisiert für Benutzer {user.username}")
        
        db_session.close()
        return jsonify({
            "success": True,
            "message": "Einstellungen erfolgreich aktualisiert"
        })
        
    except Exception as e:
        user_logger.error(f"Fehler beim Aktualisieren der Einstellungen: {str(e)}")
        return jsonify({"error": "Fehler beim Aktualisieren der Einstellungen"}), 500

@user_blueprint.route("/update-settings", methods=["POST"])
@login_required
def update_settings():
    """Benutzereinstellungen aktualisieren (Form-basiert)"""
    try:
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            flash("Benutzer nicht gefunden", "error")
            return redirect(url_for('user.settings'))
        
        # Einstellungen aus dem Formular sammeln
        settings = {}
        
        # Theme-Einstellungen
        settings['theme'] = request.form.get('theme', 'light')
        settings['language'] = request.form.get('language', 'de')
        
        # Benachrichtigungseinstellungen
        settings['email_notifications'] = request.form.get('email_notifications') == 'on'
        settings['push_notifications'] = request.form.get('push_notifications') == 'on'
        settings['job_completion_notifications'] = request.form.get('job_completion_notifications') == 'on'
        settings['printer_error_notifications'] = request.form.get('printer_error_notifications') == 'on'
        
        # Dashboard-Einstellungen
        settings['default_dashboard_view'] = request.form.get('default_dashboard_view', 'overview')
        settings['auto_refresh_interval'] = int(request.form.get('auto_refresh_interval', 30))
        
        # Privacy-Einstellungen
        settings['show_profile_publicly'] = request.form.get('show_profile_publicly') == 'on'
        settings['allow_job_sharing'] = request.form.get('allow_job_sharing') == 'on'
        
        user.settings = json.dumps(settings)
        user.updated_at = datetime.now()
        db_session.commit()
        
        user_logger.info(f"Einstellungen aktualisiert für Benutzer {user.username}")
        flash("Einstellungen erfolgreich aktualisiert", "success")
        
        db_session.close()
        return redirect(url_for('user.settings'))
        
    except Exception as e:
        user_logger.error(f"Fehler beim Aktualisieren der Einstellungen: {str(e)}")
        flash("Fehler beim Aktualisieren der Einstellungen", "error")
        return redirect(url_for('user.settings'))

@user_blueprint.route("/change-password", methods=["POST"])
@login_required
def change_password():
    """Passwort ändern"""
    try:
        # Daten aus Form oder JSON extrahieren
        if request.is_json:
            data = request.get_json()
            current_password = data.get('current_password')
            new_password = data.get('new_password')
            confirm_password = data.get('confirm_password')
        else:
            current_password = request.form.get('current_password')
            new_password = request.form.get('new_password')
            confirm_password = request.form.get('confirm_password')
        
        # Validierung
        if not all([current_password, new_password, confirm_password]):
            error_msg = "Alle Passwort-Felder sind erforderlich"
            if request.is_json:
                return jsonify({"error": error_msg}), 400
            flash(error_msg, "error")
            return redirect(url_for('user.settings'))
        
        if new_password != confirm_password:
            error_msg = "Neue Passwörter stimmen nicht überein"
            if request.is_json:
                return jsonify({"error": error_msg}), 400
            flash(error_msg, "error")
            return redirect(url_for('user.settings'))
        
        if len(new_password) < 8:
            error_msg = "Das neue Passwort muss mindestens 8 Zeichen lang sein"
            if request.is_json:
                return jsonify({"error": error_msg}), 400
            flash(error_msg, "error")
            return redirect(url_for('user.settings'))
        
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            error_msg = "Benutzer nicht gefunden"
            if request.is_json:
                return jsonify({"error": error_msg}), 404
            flash(error_msg, "error")
            return redirect(url_for('user.settings'))
        
        # Aktuelles Passwort überprüfen
        if not user.check_password(current_password):
            db_session.close()
            error_msg = "Aktuelles Passwort ist falsch"
            if request.is_json:
                return jsonify({"error": error_msg}), 401
            flash(error_msg, "error")
            return redirect(url_for('user.settings'))
        
        # Neues Passwort setzen
        user.set_password(new_password)
        user.updated_at = datetime.now()
        db_session.commit()
        
        user_logger.info(f"Passwort geändert für Benutzer {user.username}")
        
        db_session.close()
        
        success_msg = "Passwort erfolgreich geändert"
        if request.is_json:
            return jsonify({"success": True, "message": success_msg})
        flash(success_msg, "success")
        return redirect(url_for('user.settings'))
        
    except Exception as e:
        user_logger.error(f"Fehler beim Ändern des Passworts: {str(e)}")
        error_msg = "Fehler beim Ändern des Passworts"
        if request.is_json:
            return jsonify({"error": error_msg}), 500
        flash(error_msg, "error")
        return redirect(url_for('user.settings'))

@user_blueprint.route("/export", methods=["GET"])
@login_required
def export_data():
    """Benutzerdaten exportieren (DSGVO-Compliance)"""
    try:
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            flash("Benutzer nicht gefunden", "error")
            return redirect(url_for('user.settings'))
        
        # Benutzerdaten sammeln
        user_data = {
            "personal_information": {
                "id": user.id,
                "username": user.username,
                "email": user.email,
                "name": user.name,
                "department": user.department,
                "position": user.position,
                "phone": user.phone,
                "bio": user.bio,
                "role": user.role,
                "created_at": user.created_at.isoformat() if user.created_at else None,
                "last_login": user.last_login.isoformat() if user.last_login else None,
                "updated_at": user.updated_at.isoformat() if user.updated_at else None,
                "last_activity": user.last_activity.isoformat() if user.last_activity else None
            },
            "settings": json.loads(user.settings) if user.settings else {},
            "jobs": [],
            "export_date": datetime.now().isoformat(),
            "export_note": "Dies ist ein Export Ihrer persönlichen Daten gemäß DSGVO Art. 20"
        }
        
        # Benutzer-Jobs sammeln (falls verfügbar)
        try:
            from models import Job
            user_jobs = db_session.query(Job).filter(Job.user_id == user.id).all()
            for job in user_jobs:
                user_data["jobs"].append({
                    "id": job.id,
                    "filename": job.filename,
                    "status": job.status,
                    "created_at": job.created_at.isoformat() if job.created_at else None,
                    "estimated_duration": job.estimated_duration,
                    "material_used": job.material_used,
                    "notes": job.notes
                })
        except Exception as job_error:
            user_logger.warning(f"Fehler beim Sammeln der Job-Daten: {str(job_error)}")
        
        db_session.close()
        
        # JSON-Response erstellen
        response = make_response(jsonify(user_data))
        response.headers['Content-Disposition'] = f'attachment; filename=user_data_{user.username}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
        response.headers['Content-Type'] = 'application/json'
        
        user_logger.info(f"Datenexport erstellt für Benutzer {user.username}")
        
        return response
        
    except Exception as e:
        user_logger.error(f"Fehler beim Datenexport: {str(e)}")
        flash("Fehler beim Erstellen des Datenexports", "error")
        return redirect(url_for('user.settings'))

@user_blueprint.route("/profile", methods=["PUT"])
@login_required
def update_profile_api():
    """API-Endpunkt für Profil-Updates"""
    try:
        data = request.get_json()
        
        db_session = get_db_session()
        user = db_session.query(User).filter(User.id == current_user.id).first()
        
        if not user:
            db_session.close()
            return jsonify({"error": "Benutzer nicht gefunden"}), 404
        
        # Aktualisierbare Felder (ohne sensitive Daten)
        updatable_fields = ['name', 'email', 'department', 'position', 'phone', 'bio']
        
        for field in updatable_fields:
            if field in data:
                setattr(user, field, data[field])
        
        user.updated_at = datetime.now()
        db_session.commit()
        
        user_logger.info(f"Profil über API aktualisiert für Benutzer {user.username}")
        
        # Aktuelle Benutzerdaten zurückgeben
        user_data = {
            "id": user.id,
            "username": user.username,
            "email": user.email,
            "name": user.name,
            "department": user.department,
            "position": user.position,
            "phone": user.phone,
            "bio": user.bio,
            "role": user.role,
            "updated_at": user.updated_at.isoformat()
        }
        
        db_session.close()
        return jsonify({
            "success": True,
            "message": "Profil erfolgreich aktualisiert",
            "user": user_data
        })
        
    except Exception as e:
        user_logger.error(f"Fehler beim API-Profil-Update: {str(e)}")
        return jsonify({"error": "Fehler beim Aktualisieren des Profils"}), 500 