"""
Shared training utilities.

Common helpers used across all training scripts in this directory —
kept here once rather than copy-pasted six times, so a fix (e.g. to how
model metadata is saved) only needs to happen in one place.
"""

import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")


def get_logger(name: str) -> logging.Logger:
    return logging.getLogger(name)


def save_training_metadata(
    output_dir: Path,
    model_name: str,
    metrics: dict[str, Any],
    feature_cols: list[str],
    n_train: int,
    n_test: int,
) -> None:
    """
    Writes a metadata JSON alongside every .pkl artifact — this is what
    lets you (or the client) audit exactly when a model was trained, on
    how much data, and what its validation metrics were, without having
    to re-run training or dig through terminal scrollback.
    """
    metadata = {
        "model_name": model_name,
        "trained_at_utc": datetime.now(timezone.utc).isoformat(),
        "n_train_samples": n_train,
        "n_test_samples": n_test,
        "feature_columns": feature_cols,
        "metrics": metrics,
    }
    metadata_path = output_dir / f"{model_name}_metadata.json"
    with open(metadata_path, "w", encoding="utf-8") as f:
        json.dump(metadata, f, indent=2, default=str)


def check_minimum_samples(df_len: int, model_name: str, minimum: int = 100) -> None:
    if df_len < minimum:
        raise ValueError(
            f"Only {df_len} samples available for training '{model_name}', "
            f"minimum required is {minimum}. Training on fewer samples than "
            f"this produces unreliable models — collect more data or lower "
            f"this threshold deliberately (not silently)."
        )
