import datetime
from enum import StrEnum
from pathlib import Path
from typing import Literal

# Racine du depot de travail (/home/user/tp sur la VM) : lab/constants.py -> parents[1]
REPO_ROOT = Path(__file__).resolve().parents[1]

# Donnees source, deja preparees (hors git, volumineuses) : voir /data sur la VM
SOURCE_DIR = Path("/data/modelling")

# Sorties de split versionnees par DVC dans le depot
DATASET_DIR = REPO_ROOT / "data"

FEATURE_FILENAME = "features.parquet"
TARGET_FILENAME = "target.parquet"


class SplitStrategy(StrEnum):
    FULL_HISTORY = "full_history"
    RECENT_HISTORY = "recent_history"


# Strategie de split active : pilote a la fois le decoupage produit par split/cli.py
# et le parametre "split_strategy" logge dans MLflow. On la modifie (et on committe)
# a chaque changement de version de dataset pour synchroniser DVC et Git.
CHOSEN_SPLIT_STRATEGY = SplitStrategy.RECENT_HISTORY

DatasetPart = Literal["train", "test", "validation"]

DATASET_SPLIT_DATES: dict[SplitStrategy, dict[DatasetPart, tuple[datetime.date, datetime.date]]] = {
    # Partie 1 : tout l'historique disponible pour l'entrainement
    SplitStrategy.FULL_HISTORY: {
        "train": (datetime.date(2011, 1, 1), datetime.date(2012, 12, 31)),
        "validation": (datetime.date(2013, 1, 1), datetime.date(2013, 12, 31)),
        "test": (datetime.date(2014, 1, 1), datetime.date(2014, 12, 31)),
    },
    # Partie 2 : donnees plus recentes uniquement
    SplitStrategy.RECENT_HISTORY: {
        "train": (datetime.date(2013, 1, 1), datetime.date(2013, 12, 31)),
        "validation": (datetime.date(2014, 1, 1), datetime.date(2014, 5, 31)),
        "test": (datetime.date(2014, 6, 1), datetime.date(2014, 12, 31)),
    },
}


class ModellingStrategy(StrEnum):
    SHORT_MEMORY = "short_memory"
    SEASONALITY = "seasonality"
    TENDENCY = "tendency"
    MIXED = "mixed"
    FULL = "full"


Features = Literal["lag_1d", "lag_7d", "lag_30d", "lag_365d", "rolling_mean_7d", "rolling_mean_30d"]
TARGET = "consumption_kwh"

MODELLING_FEATURES: dict[ModellingStrategy, list] = {
    # La conso depend surtout de la veille
    ModellingStrategy.SHORT_MEMORY: ["lag_1d"],
    # La conso est plus saisonniere que journaliere
    ModellingStrategy.SEASONALITY: ["lag_7d", "lag_30d"],
    # La conso suit surtout une tendance
    ModellingStrategy.TENDENCY: ["rolling_mean_7d", "rolling_mean_30d"],
    # Melange lags + tendance
    ModellingStrategy.MIXED: ["lag_1d", "lag_7d", "lag_30d", "rolling_mean_30d"],
    # Toutes les features disponibles (ajoutee en Partie 2 Etape 3)
    ModellingStrategy.FULL: ["lag_1d", "lag_7d", "lag_30d", "lag_365d", "rolling_mean_7d", "rolling_mean_30d"],
}

# Valeurs d'alpha demandees par l'enonce (Partie 3)
RIDGE_ALPHAS = [1, 1e3, 1e9]


# --- TP03 : Model Registry + service de prediction ---
# Nom sous lequel les modeles sont enregistres dans le MLflow Model Registry.
# On garde un nom stable pour retrouver le modele et empiler ses versions.
REGISTERED_MODEL_NAME = "electricity-consumption"

# Alias pointant vers la version promue (chargee par l'API). On identifie le modele
# a servir par son alias (mobile) plutot que par un numero de version (fige).
MODEL_ALIAS = "champion"

# Strategie de features du modele expose par l'API : "full" (les 6 features).
# L'ordre des colonnes servies doit correspondre a celui de l'entrainement.
SERVING_STRATEGY = ModellingStrategy.FULL
SERVING_FEATURES = MODELLING_FEATURES[SERVING_STRATEGY]
