# #region SupersetDatasetsPreviewFiltersMixin [C:3] [TYPE Module] [SEMANTICS superset, dataset, preview, filter, advanced]
# @LAYER Infrastructure
# @BRIEF Filter normalization and SQL extraction helpers for dataset preview compilation.
# @RELATION DEPENDS_ON -> [SupersetClientBase]
# @RELATION DEPENDS_ON -> [SupersetDatasetsPreviewMixin]
from copy import deepcopy
from typing import Any

from ..logger import belief_scope, logger as app_logger
from ..utils.network import SupersetAPIError


# #region SupersetDatasetsPreviewFiltersMixin [C:3] [TYPE Class]
# @BRIEF Mixin providing filter normalization and compiled-SQL extraction for dataset preview operations.
# @RELATION DEPENDS_ON -> [SupersetClientBase]
# @RELATION DEPENDS_ON -> [SupersetDatasetsPreviewMixin]
class SupersetDatasetsPreviewFiltersMixin:
    # #region SupersetClientNormalizeEffectiveFiltersForQueryContext [TYPE Function] [C:3]
    # @PURPOSE: Convert execution mappings into Superset chart-data filter objects.
    def _normalize_effective_filters_for_query_context(
        self,
        effective_filters: list[dict[str, Any]],
    ) -> dict[str, Any]:
        with belief_scope(
            "SupersetClient._normalize_effective_filters_for_query_context"
        ):
            normalized_filters: list[dict[str, Any]] = []
            merged_extra_form_data: dict[str, Any] = {}
            diagnostics: list[dict[str, Any]] = []
            for item in effective_filters:
                if not isinstance(item, dict):
                    continue
                display_name = str(
                    item.get("display_name")
                    or item.get("filter_name")
                    or item.get("variable_name")
                    or "unresolved_filter"
                ).strip()
                value = item.get("effective_value")
                normalized_payload = item.get("normalized_filter_payload")
                preserved_clauses: list[dict[str, Any]] = []
                preserved_extra_form_data: dict[str, Any] = {}
                used_preserved_clauses = False
                if isinstance(normalized_payload, dict):
                    raw_clauses = normalized_payload.get("filter_clauses")
                    if isinstance(raw_clauses, list):
                        preserved_clauses = [
                            deepcopy(clause)
                            for clause in raw_clauses
                            if isinstance(clause, dict)
                        ]
                    raw_extra_form_data = normalized_payload.get("extra_form_data")
                    if isinstance(raw_extra_form_data, dict):
                        preserved_extra_form_data = deepcopy(raw_extra_form_data)
                if isinstance(preserved_extra_form_data, dict):
                    for key, extra_value in preserved_extra_form_data.items():
                        if key == "filters":
                            continue
                        merged_extra_form_data[key] = deepcopy(extra_value)
                outgoing_clauses: list[dict[str, Any]] = []
                if preserved_clauses:
                    for clause in preserved_clauses:
                        clause_copy = deepcopy(clause)
                        if "val" not in clause_copy and value is not None:
                            clause_copy["val"] = deepcopy(value)
                        outgoing_clauses.append(clause_copy)
                    used_preserved_clauses = True
                elif preserved_extra_form_data:
                    outgoing_clauses = []
                else:
                    column = str(
                        item.get("variable_name") or item.get("filter_name") or ""
                    ).strip()
                    if column and value is not None:
                        operator = "IN" if isinstance(value, list) else "=="
                        outgoing_clauses.append(
                            {"col": column, "op": operator, "val": value}
                        )
                normalized_filters.extend(outgoing_clauses)
                diagnostics.append(
                    {
                        "filter_name": display_name,
                        "value_origin": (
                            normalized_payload.get("value_origin")
                            if isinstance(normalized_payload, dict)
                            else None
                        ),
                        "used_preserved_clauses": used_preserved_clauses,
                        "outgoing_clauses": deepcopy(outgoing_clauses),
                    }
                )
                app_logger.reason(
                    "Normalized effective preview filter for Superset query context",
                    extra={
                        "filter_name": display_name,
                        "used_preserved_clauses": used_preserved_clauses,
                        "outgoing_clauses": outgoing_clauses,
                        "value_origin": (
                            normalized_payload.get("value_origin")
                            if isinstance(normalized_payload, dict)
                            else "heuristic_reconstruction"
                        ),
                    },
                )
            return {
                "filters": normalized_filters,
                "extra_form_data": merged_extra_form_data,
                "diagnostics": diagnostics,
            }
    # #endregion SupersetClientNormalizeEffectiveFiltersForQueryContext
    # #region SupersetClientExtractCompiledSqlFromPreviewResponse [TYPE Function] [C:3]
    # @PURPOSE: Normalize compiled SQL from either chart-data or legacy form_data preview responses.
    def _extract_compiled_sql_from_preview_response(
        self, response: Any
    ) -> dict[str, Any]:
        with belief_scope("SupersetClient._extract_compiled_sql_from_preview_response"):
            if not isinstance(response, dict):
                raise SupersetAPIError(
                    "Superset preview response was not a JSON object"
                )
            response_diagnostics: list[dict[str, Any]] = []
            result_payload = response.get("result")
            if isinstance(result_payload, list):
                for index, item in enumerate(result_payload):
                    if not isinstance(item, dict):
                        continue
                    compiled_sql = str(
                        item.get("query")
                        or item.get("sql")
                        or item.get("compiled_sql")
                        or ""
                    ).strip()
                    response_diagnostics.append(
                        {
                            "index": index,
                            "status": item.get("status"),
                            "applied_filters": item.get("applied_filters"),
                            "rejected_filters": item.get("rejected_filters"),
                            "has_query": bool(compiled_sql),
                            "source": "result_list",
                        }
                    )
                    if compiled_sql:
                        return {
                            "compiled_sql": compiled_sql,
                            "raw_response": response,
                            "response_diagnostics": response_diagnostics,
                        }
            top_level_candidates: list[tuple[str, Any]] = [
                ("query", response.get("query")),
                ("sql", response.get("sql")),
                ("compiled_sql", response.get("compiled_sql")),
            ]
            if isinstance(result_payload, dict):
                top_level_candidates.extend(
                    [
                        ("result.query", result_payload.get("query")),
                        ("result.sql", result_payload.get("sql")),
                        ("result.compiled_sql", result_payload.get("compiled_sql")),
                    ]
                )
            for source, candidate in top_level_candidates:
                compiled_sql = str(candidate or "").strip()
                response_diagnostics.append(
                    {"source": source, "has_query": bool(compiled_sql)}
                )
                if compiled_sql:
                    return {
                        "compiled_sql": compiled_sql,
                        "raw_response": response,
                        "response_diagnostics": response_diagnostics,
                    }
            raise SupersetAPIError(
                "Superset preview response did not expose compiled SQL "
                f"(diagnostics={response_diagnostics!r})"
            )
    # #endregion SupersetClientExtractCompiledSqlFromPreviewResponse
# #endregion SupersetDatasetsPreviewFiltersMixin
# #endregion SupersetDatasetsPreviewFiltersMixin
