"""
API routes for trace operations.
Thin controllers - delegates to service layer.
"""
from flask import Blueprint, request

from traces_explorer.backend.repositories.trace_repository import TraceRepository
from traces_explorer.backend.services.trace_parser import TraceParser
from traces_explorer.backend.services.trace_service import TraceService
from traces_explorer.backend.utils.dataiku_api import dataiku_api
from traces_explorer.backend.utils.logging import logger
from traces_explorer.backend.utils.response_utils import return_error, return_ok

traces_blueprint = Blueprint("traces", __name__, url_prefix="/traces")

# Initialize trace service (safe - routes module imported after Flask setup)
trace_service = TraceService(
    repository=TraceRepository(),
    parser=TraceParser(),
    dataiku_api=dataiku_api,
    logger=logger
)

try:
    trace_service.load_traces()
except Exception as e:
    logger.error("Failed to load traces on startup: %s", e)


@traces_blueprint.route("", methods=["GET"])
@traces_blueprint.route("/", methods=["GET"])
def list_traces():
    """List all traces (metadata only, no trace tree)."""
    try:
        traces = trace_service.list_traces()
        response_data = [trace.to_list_dict() for trace in traces]
        return return_ok(data=response_data)
    except Exception as e:
        logger.error("Error listing traces: %s", e)
        return return_error(message=f"Failed to list traces: {str(e)}")


@traces_blueprint.route("/<trace_id>", methods=["GET"])
def get_trace(trace_id: str):
    """Get trace by ID (full details with trace tree)."""
    try:
        trace = trace_service.get_trace(trace_id)

        if trace is None:
            return return_error(message="Trace not found"), 404

        return return_ok(data=trace.to_detail_dict())
    except Exception as e:
        logger.error("Error getting trace %s: %s", trace_id, e)
        return return_error(message=f"Failed to get trace: {str(e)}")


@traces_blueprint.route("", methods=["POST"])
@traces_blueprint.route("/", methods=["POST"])
def create_trace():
    """Create/import a pasted trace JSON (returns full details with trace tree)."""
    try:
        request_data = request.get_json()

        if not request_data or "traceJson" not in request_data:
            return return_error(message="Missing required field: traceJson"), 400

        trace_json = request_data["traceJson"]
        trace = trace_service.process_pasted_trace(trace_json)
        return return_ok(data=trace.to_detail_dict())

    except ValueError as e:
        # Validation errors (invalid JSON, no trace found)
        logger.warn("Validation error processing trace: %s", e)
        return return_error(message=str(e)), 400
    except Exception as e:
        logger.error("Error processing trace: %s", e)
        return return_error(message=f"Failed to process trace: {str(e)}"), 500


@traces_blueprint.route("/<trace_id>", methods=["DELETE"])
def delete_trace(trace_id: str):
    """Delete one pasted trace by ID."""
    try:
        deleted = trace_service.delete_pasted_trace(trace_id)
        if not deleted:
            return return_error(message="Pasted trace not found"), 404
        return return_ok(data={"message": "Pasted trace deleted"})
    except Exception as e:
        logger.error("Error deleting pasted trace %s: %s", trace_id, e)
        return return_error(message=f"Failed to delete pasted trace: {str(e)}"), 500


@traces_blueprint.route("", methods=["DELETE"])
@traces_blueprint.route("/", methods=["DELETE"])
def delete_traces_collection():
    """Delete traces from collection based on query filters."""
    source = request.args.get("source")
    if source != "pasted":
        return return_error(message="Missing or unsupported filter: source=pasted is required"), 400

    try:
        deleted_count = trace_service.delete_all_pasted_traces()
        return return_ok(data={"message": f"Deleted {deleted_count} pasted traces"})
    except Exception as e:
        logger.error("Error deleting all pasted traces: %s", e)
        return return_error(message=f"Failed to delete pasted traces: {str(e)}"), 500


@traces_blueprint.route("/reload", methods=["POST"])
def reload_traces():
    """Reload traces from Dataiku dataset."""
    try:
        count = trace_service.load_traces()
        return return_ok(data={"message": f"Reloaded {count} traces"})
    except Exception as e:
        logger.error("Error reloading traces: %s", e)
        return return_error(message=f"Failed to reload traces: {str(e)}")
