import logging
from typing import Any

from semantic_models.services.dss_utils import fetch_distinct_values, get_dataset_location_info, is_categorical_type
from semantic_models.utils import safe_identifier as _safe_identifier

logger = logging.getLogger(__name__)


def _fetch_sample_values(
    connection: str,
    full_table: str,
    column: str,
    dialect: str = "postgres",
    limit: int = 10,
) -> list[str]:
    try:
        # Convert to list of string values, truncating long values
        max_sample_value_length = 100
        return fetch_distinct_values(
            connection=connection,
            full_table=full_table,
            column_name=column,
            dialect=dialect,
            limit=limit,
            max_value_length=max_sample_value_length,
        )
    except ValueError as e:
        logger.warning("Skipping sample values: %s", e)
        return []
    except Exception as e:
        logger.warning("Failed to fetch sample values for %s: %s", column, e)
        return []


def get_dataset_profile(
    project_key: str,
    dataset_name: str,
    sample_value_limit: int = 0,
) -> dict[str, Any]:
    """
    Return dataset profile with label/description and column metadata.

    Includes dataset location info for internal use (connection, full_table, dialect).
    """
    _safe_identifier(project_key, "project_key")
    _safe_identifier(dataset_name, "dataset_name")

    import dataiku

    location = get_dataset_location_info(project_key, dataset_name)

    client = dataiku.api_client()
    project = client.get_project(project_key)
    dataset = project.get_dataset(dataset_name)

    try:
        metadata = dataset.get_metadata()
        dataset_description = metadata.get("description", "")
        dataset_label = metadata.get("label", "")
    except Exception:
        dataset_description = ""
        dataset_label = ""

    schema = dataset.get_schema()
    columns_info = schema.get("columns", [])

    columns: list[dict[str, Any]] = []
    for col in columns_info:
        col_name = col["name"]
        col_type = col.get("type", "string")
        col_comment = col.get("comment", "")

        sample_values = None
        if sample_value_limit > 0 and is_categorical_type(col_type):
            sample_values = _fetch_sample_values(
                connection=location.connection,
                full_table=location.full_table,
                column=col_name,
                dialect=location.dialect,
                limit=sample_value_limit,
            )

        columns.append(
            {
                "name": col_name,
                "type": col_type,
                "description": col_comment if col_comment else None,
                "sample_values": sample_values if sample_values else None,
            }
        )

    return {
        "dataset": {
            "name": dataset_name,
            "label": dataset_label if dataset_label else None,
            "description": dataset_description if dataset_description else None,
        },
        "columns": columns,
        "connection": location.connection,
        "full_table": location.full_table,
        "dialect": location.dialect,
    }
