from __future__ import annotations

import pandas as pd
from pandas.api.types import (
    is_datetime64_any_dtype,
    is_numeric_dtype,
)

def safe_to_datetime(
    series: pd.Series,
    *,
    dayfirst: bool = False,
    sample_size: int = 100,
) -> pd.Series:
    """
    Robust and quieter datetime parsing for leakage checks.

    Strategy:
    1. Return early if already datetime-like.
    2. Avoid converting numeric columns to datetime.
    3. Sample non-null string values.
    4. If sample looks ISO-like, use format='ISO8601'.
    5. Otherwise use format='mixed' for messy columns.
    """
    if is_datetime64_any_dtype(series):
        return pd.to_datetime(series, errors="coerce")

    if is_numeric_dtype(series):
        # In leakage scanning, numeric columns are usually not dates.
        return pd.Series(pd.NaT, index=series.index, dtype="datetime64[ns]")

    non_null = series.dropna()
    if non_null.empty:
        return pd.Series(pd.NaT, index=series.index, dtype="datetime64[ns]")

    sample = non_null.astype(str).head(sample_size)

    iso_like = sample.str.match(
        r"^\d{4}-\d{2}-\d{2}([ T]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})?)?$",
        na=False,
    ).mean()

    if iso_like >= 0.8:
        return pd.to_datetime(
            series,
            errors="coerce",
            format="ISO8601",
        )

    return pd.to_datetime(
        series,
        errors="coerce",
        format="mixed",
        dayfirst=dayfirst,
    )