import logging
from typing import Optional

from flask import Blueprint, jsonify, request
from pydantic import BaseModel, Field, ValidationError as PydanticValidationError
from werkzeug.exceptions import BadRequest

from semantic_models.agent.autogen_runner import AutogenRunner
from semantic_models.agentic_generation import AgenticRunner

logger = logging.getLogger(__name__)

bp = Blueprint("autogen", __name__, url_prefix="/api/autogen")

# Single switch point for autogen mode
# TODO: Move this to runtime configuration instead of source code.
AUTOGEN_MODE = "classic"  # "classic" or "agentic"


class GenerateRequest(BaseModel):
    """Request schema for /model/generate endpoint."""

    project_key: str = Field(..., description="DSS project key")
    dataset_name: str = Field(..., description="DSS dataset name")
    llm_id: str = Field(..., min_length=1, description="LLM ID")
    user_instructions: Optional[str] = Field(None, description="Instructions for entity grouping")


@bp.route("/model/generate", methods=["POST"])
def generate_model():
    try:
        data = request.get_json(silent=False)
    except BadRequest:
        return jsonify({"status": "failed", "error": "Invalid JSON body"}), 400

    if data is None:
        return jsonify({"status": "failed", "error": "No JSON body provided"}), 400

    try:
        req = GenerateRequest.model_validate(data)
    except PydanticValidationError as e:
        return jsonify({"status": "failed", "error": f"Invalid request: {e}"}), 400

    llm_id = req.llm_id
    logger.info(
        "Starting generation for %s/%s with LLM %s",
        req.project_key,
        req.dataset_name,
        llm_id,
    )

    runner = AgenticRunner(llm_id=llm_id) if AUTOGEN_MODE == "agentic" else AutogenRunner(llm_id=llm_id)

    try:
        result = runner.generate(
            project_key=req.project_key,
            dataset_name=req.dataset_name,
            user_instructions=req.user_instructions,
        )
        logger.info("Generation completed with status: %s", result.get("status"))
        return jsonify(result)
    except Exception:
        logger.exception("Generation failed with exception")
        return jsonify(
            {
                "status": "failed",
                "model": None,
                "coverage": None,
                "warnings": [],
                "error": "Internal server error",
            }
        ), 500
