"""
EN: Calculation endpoint for the BBW University Research Platform backend.
    - Handles POST requests for STL file upload and cost calculation.
    - Validates input, processes STL, and returns calculation results.
DE: Berechnungs-Endpunkt für das Backend der Forschungsplattform der bbw Hochschule.
    - Verarbeitet POST-Anfragen für STL-Upload und Kostenberechnung.
    - Validiert Eingaben, verarbeitet STL und gibt Berechnungsergebnisse zurück.
"""
from flask import request, jsonify, current_app
from app.services.berechnungsdienst import Berechnungsdienst
from app.services.validierungs_dienst import Validierungsdienst
from app.services.stl_verarbeitungs_dienst import STLVerarbeitungsdienst
from app.ausnahmen.ausnahmeverwaltung import ValidierungsFehler


def calculate_price():
    """
    EN: Handle STL upload and cost calculation request.
    DE: Verarbeitet STL-Upload und Kostenberechnungsanfrage.
    """
    if 'file' not in request.files:
        return jsonify({"error": "No STL file has been uploaded."}), 400

    file = request.files['file']
    if not file.filename or not file.filename.lower().endswith('.stl'):
        return jsonify({"error": "Invalid file type, .stl required"}), 400

    printer_name = request.form.get('printer')
    material_name = request.form.get('material')
    quality_name = request.form.get('quality')

    if not all([printer_name, material_name, quality_name]):
        return jsonify({"error": "Missing selections (printer, material, or quality)."}), 400

    try:
        import logging
        try:
            teil = STLVerarbeitungsdienst.erstelle_teil_aus_datei(file, file.filename)
        except Exception as stl_error:
            logging.error(f"Error processing STL: {stl_error}", exc_info=True)
            raise

        ressourcen = current_app.ressourcen
        drucker = ressourcen.get_drucker_by_name(printer_name)
        material = ressourcen.get_material_by_name(material_name)
        qualitaet = ressourcen.get_qualitaet_by_name(quality_name)

        if not drucker:
            raise ValidierungsFehler(
                f"Drucker '{printer_name}' nicht gefunden.",
                f"Printer '{printer_name}' not found."
            )
        if not material:
            raise ValidierungsFehler(
                f"Material '{material_name}' nicht gefunden.",
                f"Material '{material_name}' not found."
            )
        if not qualitaet:
            raise ValidierungsFehler(
                f"Qualität '{quality_name}' nicht gefunden.",
                f"Quality '{quality_name}' not found."
            )

        Validierungsdienst.pruefe_abmessungen(teil, drucker)

        gewicht_gramm = Berechnungsdienst.berechne_materialgewicht(teil, material)
        gewicht_kg = gewicht_gramm / 1000.0

        Validierungsdienst.pruefe_materialbestand(material, gewicht_kg)

        kosten = Berechnungsdienst.berechne_kosten(teil, material, drucker, qualitaet, gewicht_kg)

        return jsonify({
            "volumen_cm3": round(teil.volumen, 2),
            "abmessungen": f"{round(teil.laenge, 1)} x {round(teil.breite, 1)} x {round(teil.hoehe, 1)} mm",
            "material_gewicht_g": round(gewicht_gramm, 2),
            "druckkosten_eur": round(kosten, 2)
        })

    except ValidierungsFehler as e:
        return jsonify({"error": e.get_message_for_lang('es')}), 400
    except Exception as e:
        current_app.logger.error(f"Unexpected error in calculation: {e}", exc_info=True)
        return jsonify({"error": "Could not process the file or perform the calculation."}), 500