"""Stacking meta-confidence trainer from resolved prediction history."""

import time
from pathlib import Path

import joblib
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, roc_auc_score

from .data_loader import load_meta_prediction_frame


class StackingMetaTrainer:
    model_name = "meta_stacking"
    artifact_path = Path("models") / "meta_stacking.joblib"

    def run(self, days: int = 180) -> dict:
        start = time.time()
        frame = load_meta_prediction_frame(days)
        if frame.empty or len(frame) < 50:
            return {
                "model": self.model_name,
                "status": "skipped",
                "metrics": {"samples": len(frame)},
                "duration_seconds": round(time.time() - start, 2),
                "artifact_path": "",
                "error": "Need at least 50 resolved predictions",
            }

        encoded = frame.copy()
        y = encoded.pop("was_correct").astype(int)
        encoded = encoded.drop(columns=["actual_change_pct"])
        encoded = encoded.fillna(0.0)
        encoded = encoded.astype({"model": "string", "horizon": "string"})
        encoded = pd.get_dummies(encoded, columns=["model", "horizon"], dtype=float)

        n = len(encoded)
        split = int(n * 0.80)
        X_train, X_test = encoded.iloc[:split], encoded.iloc[split:]
        y_train, y_test = y.iloc[:split], y.iloc[split:]

        model = LogisticRegression(max_iter=1000, class_weight="balanced", random_state=42)
        model.fit(X_train, y_train)

        proba = model.predict_proba(X_test)[:, 1]
        pred = (proba >= 0.5).astype(int)
        accuracy = float(accuracy_score(y_test, pred))
        auc = float(roc_auc_score(y_test, proba)) if len(set(y_test)) > 1 else 0.5

        self.artifact_path.parent.mkdir(parents=True, exist_ok=True)
        joblib.dump(
            {
                "model": model,
                "columns": list(X_train.columns),
                "trained_at": str(int(time.time())),
                "accuracy": accuracy,
                "auc": auc,
            },
            self.artifact_path,
        )

        return {
            "model": self.model_name,
            "status": "success",
            "metrics": {
                "accuracy": accuracy,
                "auc": auc,
                "train_samples": len(X_train),
                "test_samples": len(X_test),
            },
            "duration_seconds": round(time.time() - start, 2),
            "artifact_path": str(self.artifact_path),
        }
