import pandas as pd

TIME_KEYWORDS = ["date", "time", "month", "year", "quarter", "posted", "report"]
AMOUNT_KEYWORDS = [
    "amount",
    "payment",
    "revenue",
    "charge",
    "adjustment",
    "withheld",
    "count",
    "ar",
    "balance",
]
ID_KEYWORDS = ["id", "key", "uuid"]


def is_time_column(series: pd.Series) -> bool:
    name = series.name.lower()

    if any(k in name for k in TIME_KEYWORDS):
        return True

    return pd.api.types.is_datetime64_any_dtype(series)


def is_flag_column(series: pd.Series) -> bool:
    if series.nunique() == 2:
        if series.dropna().isin([0, 1, True, False]).all():
            return True
    return False


def is_identifier_column(series: pd.Series) -> bool:
    name = series.name.lower()

    # Metric-like columns should never be treated as identifiers.
    if any(k in name for k in AMOUNT_KEYWORDS):
        return False

    if any(k in name for k in ID_KEYWORDS):
        return True

    # IDs are usually integers or strings, not float measures.
    if pd.api.types.is_integer_dtype(series):
        uniqueness = series.nunique() / max(len(series), 1)
        return uniqueness > 0.95

    return False


def is_metric_column(series: pd.Series) -> bool:
    name = series.name.lower()

    if any(k in name for k in AMOUNT_KEYWORDS):
        return True

    if pd.api.types.is_numeric_dtype(series):
        # Small summary datasets can still be valid metrics with few rows.
        if len(series) < 10:
            return series.nunique() > 1
        return series.nunique() > 5

    return False


def is_dimension_column(series: pd.Series) -> bool:
    unique = series.nunique()
    return series.dtype == "object" and 2 <= unique <= 20
