import enum
from flask import Blueprint, request, jsonify
from models.factory_structure_model import Machine, Parameter, ParameterDomain, ParameterValue
from models.dashboard_model import DashboardWidget
from extensions import db

factory_struct_api_bp = Blueprint("factory_struct_api", __name__)


# ============================================
# GET MACHINES
# ============================================

@factory_struct_api_bp.route("/api/get/machines")
def get_machines():

    machines = Machine.query.all()

    result = []

    for machine in machines:
        machine:Machine
        result.append({
            "id": machine.id,
            "name": machine.name,
            "display_name": machine.display_name,
            "machine_type": machine.machine_type,
            "location": machine.location,
            "status": machine.status,
            "meta": machine.meta,
            "created_at": machine.created_at.isoformat()
        })

    return jsonify(result), 200


# ============================================
# CREATE MACHINE
# ============================================
@factory_struct_api_bp.route('/api/save/machine', methods=['POST'])
def save_machine():

    try:
        data = request.get_json()

        if not data:
            return jsonify({"success": False, "message": "Invalid JSON"}), 400

        machine_data = data.get("machine")
        parameters = data.get("parameters", [])

        if not machine_data:
            return jsonify({"success": False, "message": "Machine data required"}), 422

        machine_id = machine_data.get('id')
        machine = None
        if machine_id:
            machine = Machine.query.get(machine_id)

        # create new or edit not exist machine
        if machine is None:
            machine = Machine()

        # =========================
        # replace parms
        # =========================
        machine:Machine
        machine.name = machine_data["name"]
        machine.display_name = machine_data["display_name"]
        machine.machine_type = machine_data["machine_type"]
        machine.status = machine_data["status"]
        machine.location = machine_data["location"]
        machine.meta = machine_data.get("meta", {})

        db.session.add(machine)
        db.session.flush()  # get machine.id before commit

        # =========================
        # Remove Deleted Parameters
        # =========================
        new_parms_ids = []
        for p in parameters:
            new_parms_ids.append(p.get('id'))

        for current_p in machine.parameters:
            if current_p.id not in new_parms_ids:
                db.session.delete(current_p)

        # =========================
        # CREATE OR EDIR PARAMETERS
        # =========================
        for p in parameters:
            p_id = p.get('id')
            parameter = None
            if p_id:
                parameter = Parameter.query.get(p_id)
            
            if parameter is None:
                parameter = Parameter()

            parameter.name = p["name"]
            parameter.machine_id=machine.id
            parameter.name=p["name"]
            parameter.display_name= p["display_name"]
            parameter.tag= p.get("tag")
            parameter.min_value= p.get("min_value")
            parameter.max_value= p.get("max_value")
            parameter.domain=ParameterDomain(p["domain"])
            parameter.data_type=p["data_type"]
            parameter.unit=p.get("unit")
            parameter.description=p.get("description")
            
            db.session.add(parameter)

        
        

        db.session.commit()

        return jsonify({
            "success": True,
            "machine_id": machine.id
        }), 201

    except Exception as e:
        db.session.rollback()
        return jsonify({
            "success": False,
            "message": str(e)
        }), 500
    


@factory_struct_api_bp.route("/api/machines/get-machine-full/<int:machine_id>", methods=["GET"])
def get_machine_full(machine_id):

    try:
        # =========================
        # Get machine
        # =========================
        machine = Machine.query.get(machine_id)

        if not machine:
            return jsonify({
                "success": False,
                "message": "Machine not found"
            }), 404

        # =========================
        # Get parameters
        # =========================
        params = Parameter.query.filter_by(machine_id=machine_id).all()

        # =========================
        # Serialize machine
        # =========================
        machine_data = {
            "id": machine.id,
            "name": machine.name,
            "display_name": machine.display_name,
            "machine_type": machine.machine_type,
            "status": machine.status,
            "location": machine.location
        }

        # =========================
        # Serialize parameters
        # =========================
        parameters_data = []

        for p in params:
            parameters_data.append({
                "id": p.id,
                "name": p.name,
                "display_name": p.display_name,
                "max_value": p.max_value,
                "min_value": p.min_value,
                "tag": p.tag,
                "domain": p.domain.value,
                "data_type": p.data_type,
                "unit": p.unit,
                "description": p.description
            })

        # =========================
        # Response
        # =========================
        return jsonify({
            "success": True,
            "data": {
                "machine": machine_data,
                "parameters": parameters_data
            }
        })

    except Exception as e:
        return jsonify({
            "success": False,
            "message": str(e)
        }), 500
    



@factory_struct_api_bp.route("/api/machines/delete-full/<int:machine_id>", methods=["DELETE"])
def delete_machine(machine_id):

    try:
        # =========================
        # 1. Get machine
        # =========================
        machine = Machine.query.get(machine_id)

        if not machine:
            return jsonify({
                "success": False,
                "message": "Machine not found"
            }), 404

        # =========================
        # 2. Explicitly delete parameter values (safe + explicit control)
        # =========================
        for param in machine.parameters:

            # delete all values of each parameter
            ParameterValue.query.filter_by(parameter_id=param.id).delete()

        # =========================
        # 3. Delete dashboard widgets connected to the machine or its parameters
        # =========================
        parameter_ids = [param.id for param in machine.parameters]
        if parameter_ids:
            DashboardWidget.query.filter(
                DashboardWidget.parameter_id.in_(parameter_ids)
            ).delete(synchronize_session=False)

        DashboardWidget.query.filter_by(
            machine_id=machine_id
        ).delete(synchronize_session=False)

        # =========================
        # 4. Delete parameters
        # =========================
        Parameter.query.filter_by(machine_id=machine_id).delete()

        # =========================
        # 5. Delete machine
        # =========================
        db.session.delete(machine)

        db.session.commit()

        return jsonify({
            "success": True,
            "message": "Machine and all related data deleted successfully"
        })

    except Exception as e:
        db.session.rollback()

        return jsonify({
            "success": False,
            "message": str(e)
        }), 500