"""Short-horizon microstructure specialist for 1m-15m direction calls."""

import os
from pathlib import Path

import joblib
import numpy as np

MODEL_DIR = Path(os.getenv("MODEL_DIR", "models"))


class MicrostructureSpecialist:
    FEATURE_KEYS = [
        "return_1",
        "volume_ratio",
        "range_pct",
        "wick_imbalance",
        "trade_intensity",
        "price_vs_sma20",
        "volatility_5",
    ]

    def __init__(self) -> None:
        self.version = "0.1.0"
        self.is_loaded = False
        self.last_trained: str | None = None
        self.accuracy: float | None = None
        self.model = None

    def load(self) -> None:
        path = MODEL_DIR / "microstructure_specialist.joblib"
        try:
            data = joblib.load(path)
            self.model = data["model"]
            self.last_trained = data.get("trained_at")
            self.accuracy = data.get("accuracy")
            self.is_loaded = True
        except Exception:
            self.model = None
            self.is_loaded = True

    def predict(self, features: dict) -> dict:
        if self.model is None:
            score = float(features.get("return_1", 0.0)) * 0.8 + (
                float(features.get("volume_ratio", 1.0)) - 1.0
            ) * 0.2
            direction = "up" if score > 0.15 else "down" if score < -0.15 else "sideways"
            probability = min(0.7, 0.5 + abs(score) / 5)
            return {
                "direction": direction,
                "probability": round(probability, 4),
                "confidence": round(probability * 100, 2),
                "model": "heuristic-microstructure",
            }

        x = np.array([[features.get(k, 0.0) for k in self.FEATURE_KEYS]], dtype=np.float32)
        proba = self.model.predict_proba(x)[0]
        idx = int(np.argmax(proba))
        direction = {0: "down", 1: "sideways", 2: "up"}.get(idx, "sideways")
        return {
            "direction": direction,
            "probability": round(float(proba[idx]), 4),
            "confidence": round(float(proba[idx]) * 100, 2),
            "model": "microstructure_specialist",
        }
