import logging
from datetime import datetime, timezone

from flask import Blueprint, jsonify, request

logger = logging.getLogger(__name__)

bp = Blueprint("indexing", __name__, url_prefix="/api/semantic-models")


@bp.route("/<model_id>/versions/<version_id>/indexing/start", methods=["POST"])
def start_distinct_values_indexing(model_id: str, version_id: str):
    try:
        import dataiku

        client = dataiku.api_client()
        project = client.get_default_project()
        sm = project.get_semantic_model(model_id)
        version = sm.get_version(version_id)

        future = version.start_update_distinct_values()

        return jsonify({"jobId": future.job_id})

    except Exception:
        logger.exception("Failed to start distinct-values indexing")
        raise


@bp.route("/<model_id>/versions/<version_id>/indexing/status/<job_id>", methods=["GET"])
def get_distinct_values_indexing_status(model_id: str, version_id: str, job_id: str):
    try:
        import dataiku

        client = dataiku.api_client()
        future = client.get_future(job_id)
        state = future.peek_state()
        return jsonify(state)

    except Exception:
        logger.exception("Failed to fetch distinct-values indexing status")
        raise


@bp.route("/<model_id>/versions/<version_id>/indexing/rebuild-indices", methods=["POST"])
def rebuild_value_indices(model_id: str, version_id: str):
    try:
        from semantic_models.routes.common import build_spec_from_version, get_service
        from semantic_models.resolution.index import collect_sources_from_spec, initialize_value_indices_from_sources
        from semantic_models.resolution import clear_source_index

        service = get_service()
        version = service.get_version(model_id, version_id)
        spec_dict = build_spec_from_version(version).model_dump()

        data = request.get_json(silent=True) or {}
        embedding_llm_id = None
        raw_embedding = data.get("embedding_llm_id")
        if isinstance(raw_embedding, str) and raw_embedding.strip():
            embedding_llm_id = raw_embedding.strip()

        sources = collect_sources_from_spec(model_id, version_id, spec_dict)
        for source, _columns in sources:
            clear_source_index(source)

        results = initialize_value_indices_from_sources(
            sources=sources,
            embedding_llm_id=embedding_llm_id,
            spec_dict=spec_dict,
        )

        last_indexed_at = datetime.now(timezone.utc).isoformat()
        try:
            import dataiku

            client = dataiku.api_client()
            project = client.get_default_project()
            sm = project.get_semantic_model(model_id)
            version = sm.get_version(version_id)
            settings = version.get_settings()
            raw = settings.get_raw()
            private = raw.get("privateEditorData")
            if not isinstance(private, dict):
                private = {}
            private["indexingStale"] = False
            private["lastIndexedAt"] = last_indexed_at
            if embedding_llm_id:
                private["lastIndexedEmbeddingLlmId"] = embedding_llm_id
            else:
                private.pop("lastIndexedEmbeddingLlmId", None)
            raw["privateEditorData"] = private
            settings.save()
        except Exception as e:
            logger.warning("Failed to mark indexing fresh on version %s: %s", version_id, e)

        return jsonify({"results": results, "lastIndexedAt": last_indexed_at})

    except Exception:
        logger.exception("Failed to rebuild plugin indices")
        raise
