"""
Topic Registry — maps user-friendly topic names to content modules.
"""

from vexray.topics import (
    linear_regression,
    logistic_regression,
    decision_trees,
    random_forest,
    svm,
    knn,
    naive_bayes,
    kmeans,
    pca,
    gradient_boosting,
    regularization,
    bias_variance,
    cross_validation,
    neural_networks,
    backpropagation,
    cnn,
    rnn_lstm,
    transformers,
    gans,
    autoencoders,
    activation_functions,
    loss_functions,
    optimizers,
)

# Maps lowercase aliases → topic module
_TOPIC_MAP = {
    # Linear Regression
    "linear regression": linear_regression,
    "linear_regression": linear_regression,
    "lr": linear_regression,

    # Logistic Regression
    "logistic regression": logistic_regression,
    "logistic_regression": logistic_regression,
    "logistic": logistic_regression,

    # Decision Trees
    "decision trees": decision_trees,
    "decision_trees": decision_trees,
    "decision tree": decision_trees,
    "dt": decision_trees,

    # Random Forest
    "random forest": random_forest,
    "random_forest": random_forest,
    "rf": random_forest,

    # Support Vector Machines
    "support vector machines": svm,
    "support vector machine": svm,
    "svm": svm,

    # K-Nearest Neighbors
    "k-nearest neighbors": knn,
    "k nearest neighbors": knn,
    "knn": knn,

    # Naive Bayes
    "naive bayes": naive_bayes,
    "naive_bayes": naive_bayes,
    "nb": naive_bayes,

    # K-Means Clustering
    "k-means clustering": kmeans,
    "k-means": kmeans,
    "kmeans": kmeans,

    # Principal Component Analysis
    "principal component analysis": pca,
    "pca": pca,

    # Gradient Boosting
    "gradient boosting": gradient_boosting,
    "gradient_boosting": gradient_boosting,
    "gbm": gradient_boosting,
    "xgboost": gradient_boosting,

    # Regularization
    "regularization": regularization,
    "ridge": regularization,
    "lasso": regularization,

    # Bias-Variance Tradeoff
    "bias-variance tradeoff": bias_variance,
    "bias variance tradeoff": bias_variance,
    "bias variance": bias_variance,
    "bias_variance": bias_variance,

    # Cross-Validation
    "cross-validation": cross_validation,
    "cross validation": cross_validation,
    "cross_validation": cross_validation,
    "cv": cross_validation,

    # ── Deep Learning Topics ──

    # Neural Networks
    "neural networks": neural_networks,
    "neural network": neural_networks,
    "neural_networks": neural_networks,
    "nn": neural_networks,

    # Backpropagation
    "backpropagation": backpropagation,
    "backprop": backpropagation,

    # CNNs
    "convolutional neural networks": cnn,
    "convolutional neural network": cnn,
    "cnn": cnn,
    "cnns": cnn,
    "convnets": cnn,

    # RNNs & LSTMs
    "rnns & lstms": rnn_lstm,
    "rnn": rnn_lstm,
    "rnns": rnn_lstm,
    "lstm": rnn_lstm,
    "lstms": rnn_lstm,
    "recurrent neural networks": rnn_lstm,

    # Transformers & Attention
    "transformers & attention": transformers,
    "transformers": transformers,
    "transformer": transformers,
    "attention": transformers,
    "self-attention": transformers,

    # GANs
    "gans": gans,
    "gan": gans,
    "generative adversarial networks": gans,

    # Autoencoders
    "autoencoders": autoencoders,
    "autoencoder": autoencoders,
    "vae": autoencoders,

    # Activation Functions
    "activation functions": activation_functions,
    "activation_functions": activation_functions,
    "activations": activation_functions,
    "relu": activation_functions,

    # Loss Functions
    "loss functions": loss_functions,
    "loss_functions": loss_functions,
    "loss": loss_functions,

    # Optimizers
    "optimizers": optimizers,
    "optimizer": optimizers,
    "adam": optimizers,
    "sgd": optimizers,
}


def get_topic(name: str):
    """
    Resolve a topic name to its content module.
    Raises ValueError with a helpful message if not found.
    """
    key = name.strip().lower()
    if key in _TOPIC_MAP:
        return _TOPIC_MAP[key]

    available = sorted(set(
        k for k in _TOPIC_MAP.keys()
        if not k.startswith("_")
    ))
    raise ValueError(
        f"Unknown topic: '{name}'.\n"
        f"Available topics: {', '.join(available)}"
    )


def list_topics() -> list[str]:
    """Return a list of canonical topic names."""
    seen = set()
    result = []
    for module in _TOPIC_MAP.values():
        name = module.get_content()["title"]
        if name not in seen:
            seen.add(name)
            result.append(name)
    return sorted(result)
