import os
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score

BITACORA = os.path.join(os.path.dirname(__file__), '..', 'outputs', 'bitacora_experimentos.csv')
FIGURES_PATH = os.path.join(os.path.dirname(__file__), '..', 'outputs', 'figures')


def metricas(y_true, y_pred, sufijo):
    """Calcula precision, recall, f1 y accuracy (macro) para un split."""
    return {
        f'precision_{sufijo}': precision_score(y_true, y_pred, average='macro', zero_division=0),
        f'recall_{sufijo}':    recall_score(y_true, y_pred, average='macro', zero_division=0),
        f'f1_{sufijo}':        f1_score(y_true, y_pred, average='macro', zero_division=0),
        f'accuracy_{sufijo}':  accuracy_score(y_true, y_pred),
    }


def registrar(exp_id, modelo, hiperparams, arquitectura, model, X_train, y_train, X_test, y_test):
    """Append de una fila de experimento a la bitácora CSV."""
    fila = {
        'experimento_id': exp_id,
        'modelo': modelo,
        'hiperparametros': str(hiperparams),
        'arquitectura': arquitectura,
    }
    fila.update(metricas(y_train, model.predict(X_train), 'train'))
    fila.update(metricas(y_test,  model.predict(X_test),  'test'))

    path = os.path.abspath(BITACORA)
    os.makedirs(os.path.dirname(path), exist_ok=True)
    write_header = not os.path.exists(path)
    pd.DataFrame([fila]).to_csv(path, mode='a', header=write_header, index=False)
    print(f"[bitacora] {modelo} | {exp_id} | F1 test={fila['f1_test']:.4f}")


def plot_importancia(model, feature_names, titulo, top_n=16, save=True):
    """Barplot horizontal de feature importances ordenado descendentemente."""
    importancias = pd.Series(model.feature_importances_, index=feature_names)
    importancias = importancias.nlargest(top_n).sort_values()

    fig, ax = plt.subplots(figsize=(8, max(4, top_n * 0.4)))
    importancias.plot(kind='barh', ax=ax)
    ax.set_title(titulo)
    ax.set_xlabel('Importancia')
    plt.tight_layout()

    if save:
        os.makedirs(os.path.abspath(FIGURES_PATH), exist_ok=True)
        filename = titulo.lower().replace(' ', '_').replace('—', '').replace('/', '_').strip('_') + '.png'
        path = os.path.join(os.path.abspath(FIGURES_PATH), filename)
        fig.savefig(path, dpi=150)
        print(f"[figura] guardada en {path}")

    plt.show()
    return importancias
