from flask import Blueprint, jsonify, request

from hiveos.api.context import authorize_core_action, emit_action_applied, emit_action_failed


control_bp = Blueprint("control", __name__)


@control_bp.route("/freeze_zone", methods=["POST"])
def freeze_zone():
    action = "control.freeze_zone"
    zone_id = None
    try:
        data = request.json
        zone_id = (data or {}).get("zone_id")
        if not zone_id:
            return jsonify({"error": "Missing 'zone_id' field"}), 400
        core = authorize_core_action(action, resource_type="zone", resource_id=zone_id)

        zone = core.zones.get(zone_id)
        if not zone:
            emit_action_failed(action, resource_type="zone", resource_id=zone_id, reason="zone_not_found")
            return jsonify({"error": f"No zone found with zone_id {zone_id}"}), 404

        zone.frozen = True
        emit_action_applied(action, resource_type="zone", resource_id=zone_id)
        print(f"[Zone {zone.zone_id}] Frozen.")
        return jsonify({"message": f"Zone {zone.zone_id} frozen."}), 200
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    except Exception as e:
        import traceback

        traceback.print_exc()
        emit_action_failed(action, resource_type="zone", reason=e, resource_id=zone_id)
        return jsonify({"error": str(e)}), 500


@control_bp.route("/unfreeze_zone", methods=["POST"])
def unfreeze_zone():
    action = "control.unfreeze_zone"
    zone_id = None
    try:
        data = request.json
        zone_id = (data or {}).get("zone_id")
        if not zone_id:
            return jsonify({"error": "Missing 'zone_id' field"}), 400
        core = authorize_core_action(action, resource_type="zone", resource_id=zone_id)

        zone = core.zones.get(zone_id)
        if not zone:
            emit_action_failed(action, resource_type="zone", resource_id=zone_id, reason="zone_not_found")
            return jsonify({"error": f"No zone found with zone_id {zone_id}"}), 404

        zone.frozen = False
        emit_action_applied(action, resource_type="zone", resource_id=zone_id)
        print(f"[Zone {zone.zone_id}] Resumed.")
        return jsonify({"message": f"Zone {zone.zone_id} resumed."}), 200
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    except Exception as e:
        import traceback

        traceback.print_exc()
        emit_action_failed(action, resource_type="zone", reason=e, resource_id=zone_id)
        return jsonify({"error": str(e)}), 500


@control_bp.route("/kill_zone", methods=["POST"])
def kill_zone():
    action = "control.kill_zone"
    data = request.get_json()
    zone_id = data.get("zone_id")
    try:
        core = authorize_core_action(action, resource_type="zone", resource_id=zone_id)
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    zone = core.zones.get(zone_id)

    if zone:
        zone.should_shutdown = True
        emit_action_applied(action, resource_type="zone", resource_id=zone_id)
        return jsonify({"status": "shutdown_queued", "zone_id": zone_id})
    emit_action_failed(action, resource_type="zone", resource_id=zone_id, reason="zone_not_found")
    return jsonify({"error": f"No zone found with zone_id {zone_id}"}), 404


@control_bp.route("/pause_core", methods=["POST"])
def pause_core():
    action = "control.pause_core"
    try:
        core = authorize_core_action(action, resource_type="session")
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    core.tick_control["running"] = False
    emit_action_applied(action, resource_type="session")
    print(f"[Core{id(core)}] Tick paused")
    return jsonify({"message": "Core paused"}), 200


@control_bp.route("/resume_core", methods=["POST"])
def resume_core():
    action = "control.resume_core"
    try:
        core = authorize_core_action(action, resource_type="session")
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    core.tick_control["running"] = True
    emit_action_applied(action, resource_type="session")
    print(f"[Core{id(core)}] Tick resumed")
    return jsonify({"message": "Core resumed"}), 200


@control_bp.route("/shutdown_core", methods=["POST"])
def shutdown_core():
    action = "control.shutdown_core"
    try:
        _ = authorize_core_action(action, resource_type="session")
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    emit_action_applied(action, resource_type="session")
    print("[Stub] Shutdown core")
    return jsonify({"message": "Core shutdown stub"}), 200


@control_bp.route("/set_tickrate", methods=["POST"])
def set_tickrate():
    action = "control.set_tickrate"
    try:
        data = request.json
        tickrate = float(data.get("tickrate", 0.1))

        if tickrate < 0.01:
            return jsonify({"error": "Tickrate must be >= 0.01"}), 400
        core = authorize_core_action(action, resource_type="session")

        core.tick_control["delay"] = tickrate
        emit_action_applied(action, resource_type="session", payload={"tickrate": tickrate})
        print(f"[Core] Tickrate set to {tickrate} seconds")
        return jsonify({"message": f"Tickrate updated to {tickrate}"}), 200
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    except Exception as e:
        import traceback

        traceback.print_exc()
        emit_action_failed(action, resource_type="session", reason=e)
        return jsonify({"error": str(e)}), 500


@control_bp.route("/step_tick", methods=["POST"])
def step_tick():
    action = "control.step_tick"
    try:
        core = authorize_core_action(action, resource_type="session")
    except PermissionError as e:
        return jsonify({"error": str(e)}), 403
    try:
        if core.tick_control["running"]:
            core.tick_control["running"] = False
            print("[Core] Auto-paused before step")

        core.tick()
        core.tick_counter["count"] += 1
        emit_action_applied(action, resource_type="session", payload={"tick_count": core.tick_counter["count"]})
        print("[Core] Step tick executed")
        return jsonify({"message": "Tick stepped"}), 200
    except Exception as e:
        import traceback

        traceback.print_exc()
        emit_action_failed(action, resource_type="session", reason=e)
        return jsonify({"error": str(e)}), 500
