"""Research catalog for exactness-focused model expansion.

This module turns the ML roadmap into structured data the API can expose.
The intent is not to claim deterministic "exact predictions"; instead it
describes the model families, engines, and rollout phases required to push
Vizzor toward tighter directional accuracy, better price targeting, narrower
intervals, and better calibration.
"""

from __future__ import annotations

from collections import Counter


def _entry(
    model_id: str,
    name: str,
    category: str,
    engine: str,
    target: str,
    horizons: list[str],
    feature_groups: list[str],
    training_cadence: str,
    exactness_role: str,
    rollout_phase: str,
    status: str = "candidate",
) -> dict:
    return {
        "id": model_id,
        "name": name,
        "category": category,
        "engine": engine,
        "target": target,
        "horizons": horizons,
        "feature_groups": feature_groups,
        "training_cadence": training_cadence,
        "exactness_role": exactness_role,
        "rollout_phase": rollout_phase,
        "status": status,
    }


MODEL_CATALOG = [
    # Directional core
    _entry("direction_xgb_scalp", "XGBoost Direction Scalp", "directional_core", "xgboost", "3-class next-move classification", ["5m", "15m", "30m"], ["ohlcv", "technical", "derivatives", "microstructure"], "hourly", "Fast low-latency directional backbone for scalp horizons", "phase_1", "active"),
    _entry("direction_xgb_standard", "XGBoost Direction Standard", "directional_core", "xgboost", "3-class next-move classification", ["1h", "4h"], ["ohlcv", "technical", "sentiment", "derivatives"], "6h", "Main production classifier for standard intraday horizons", "phase_1", "active"),
    _entry("direction_xgb_position", "XGBoost Direction Position", "directional_core", "xgboost", "3-class next-move classification", ["1d", "7d"], ["ohlcv", "macro", "onchain", "prediction_markets"], "daily", "Slower higher-context classifier for swing horizons", "phase_1", "active"),
    _entry("direction_lgbm_multihorizon", "LightGBM Direction Multi-Horizon", "directional_core", "lightgbm", "3-class multi-horizon classification", ["15m", "1h", "4h", "1d"], ["ohlcv", "technical", "market_snapshots"], "6h", "Benchmark alternative to XGBoost for tree-based direction", "phase_2"),
    _entry("direction_catboost_contextual", "CatBoost Direction Contextual", "directional_core", "catboost", "3-class context-aware classification", ["1h", "4h", "1d"], ["technical", "onchain", "sentiment", "metadata"], "daily", "Handles mixed numeric and categorical context with less preprocessing", "phase_2"),
    _entry("direction_temporal_cnn", "Temporal CNN Direction", "directional_core", "pytorch-temporal-cnn", "3-class sequence classification", ["5m", "15m", "1h"], ["ohlcv_sequences", "derived_indicators"], "6h", "Captures short-term local structure missed by tabular trees", "phase_2"),
    _entry("direction_tcn", "Temporal Convolution Network Direction", "directional_core", "pytorch-tcn", "3-class sequence classification", ["15m", "1h", "4h"], ["ohlcv_sequences", "derivatives_sequences"], "6h", "Longer receptive field directional learner with predictable latency", "phase_2"),
    _entry("direction_transformer_encoder", "Transformer Encoder Direction", "directional_core", "pytorch-transformer", "3-class sequence classification", ["1h", "4h", "1d"], ["multi_source_sequences", "event_flags"], "daily", "High-capacity sequence benchmark for cross-signal timing", "phase_3"),
    # Target regression
    _entry("target_xgb_quantile", "XGBoost Quantile Target", "target_regression", "xgboost", "price delta regression", ["15m", "1h", "4h"], ["technical", "ohlcv", "derivatives"], "6h", "Produces tighter bull/base/bear target ladders", "phase_1"),
    _entry("target_lightgbm_quantile", "LightGBM Quantile Target", "target_regression", "lightgbm", "quantile target regression", ["1h", "4h", "1d"], ["technical", "onchain", "sentiment"], "6h", "Fast interval-aware target model for production A/B tests", "phase_2"),
    _entry("target_catboost_delta", "CatBoost Target Delta", "target_regression", "catboost", "next-horizon return regression", ["1h", "4h", "1d"], ["technical", "macro", "market_metadata"], "daily", "Robust target model when metadata shifts across assets", "phase_2"),
    _entry("target_elasticnet_baseline", "ElasticNet Target Baseline", "target_regression", "sklearn-elasticnet", "linear target regression", ["1h", "4h", "1d"], ["technical", "macro"], "daily", "Low-variance baseline and residual anchor for ensembles", "phase_1"),
    _entry("target_random_forest_residual", "Random Forest Residual Target", "target_regression", "sklearn-rf", "residual regression", ["1h", "4h"], ["base_model_residuals", "technical"], "6h", "Learns non-linear residual corrections on top of baseline targets", "phase_2"),
    _entry("target_ngboost_distribution", "NGBoost Return Distribution", "target_regression", "ngboost", "distributional return regression", ["1h", "4h", "1d"], ["technical", "onchain", "sentiment"], "daily", "Predicts both expected move and uncertainty together", "phase_3"),
    _entry("target_nbeats_sequence", "N-BEATS Target Forecaster", "target_regression", "pytorch-nbeats", "multi-step point forecast", ["4h", "1d", "7d"], ["ohlcv_sequences", "seasonality"], "daily", "Sequence model for cleaner medium-horizon price trajectories", "phase_3"),
    _entry("target_nhits_sequence", "N-HiTS Target Forecaster", "target_regression", "pytorch-nhits", "multi-step point forecast", ["4h", "1d", "7d"], ["ohlcv_sequences", "event_sequences"], "daily", "Long-horizon benchmark with strong time-series inductive bias", "phase_3"),
    # Interval and uncertainty
    _entry("interval_quantile_random_forest", "Quantile Random Forest Interval", "interval_uncertainty", "quantile-rf", "prediction interval estimation", ["1h", "4h", "1d"], ["technical", "residuals"], "6h", "Generates fallback bull/base/bear bands without neural infra", "phase_2"),
    _entry("interval_conformal_calibrator", "Conformal Interval Calibrator", "interval_uncertainty", "conformal", "distribution-free interval calibration", ["15m", "1h", "4h", "1d"], ["model_errors", "residual_history"], "hourly", "Keeps target bands honest under distribution shift", "phase_1", "active"),
    _entry("interval_tft_quantile", "Temporal Fusion Transformer Quantile", "interval_uncertainty", "pytorch-tft", "quantile time-series forecasting", ["4h", "1d", "7d"], ["multi_source_sequences", "known_future_covariates"], "daily", "Quantile forecasts with interpretable attention and gating", "phase_3"),
    _entry("interval_deepar_distribution", "DeepAR Distribution Forecaster", "interval_uncertainty", "pytorch-deepar", "probabilistic sequence forecasting", ["4h", "1d", "7d"], ["ohlcv_sequences", "covariates"], "daily", "Probabilistic benchmark for medium-horizon path forecasts", "phase_3"),
    _entry("interval_bsts", "Bayesian Structural Time Series", "interval_uncertainty", "bsts", "component-based probabilistic forecasting", ["1d", "7d"], ["price", "seasonality", "macro"], "daily", "Stable uncertainty model when sample sizes are small", "phase_3"),
    _entry("interval_mdn", "Mixture Density Network", "interval_uncertainty", "pytorch-mdn", "mixture distribution regression", ["1h", "4h", "1d"], ["technical", "onchain", "sentiment"], "daily", "Captures multi-modal outcomes in event-heavy markets", "phase_4"),
    # Regime and state
    _entry("regime_hmm", "Hidden Markov Regime Detector", "regime_state", "hmmlearn", "latent market state classification", ["1h", "4h", "1d"], ["returns", "volatility", "volume"], "6h", "Baseline latent state engine for regime-aware routing", "phase_1", "active"),
    _entry("regime_hsmm", "Hidden Semi-Markov Regime Detector", "regime_state", "pyhsmm", "duration-aware state classification", ["4h", "1d"], ["returns", "volatility", "macro"], "daily", "Improves state persistence and regime duration modeling", "phase_2"),
    _entry("regime_markov_switching_ar", "Markov Switching AR", "regime_state", "statsmodels-markov", "switching autoregressive regime inference", ["4h", "1d"], ["returns", "volatility"], "daily", "Useful benchmark for interpretable bull/bear transitions", "phase_2"),
    _entry("regime_change_point", "Bayesian Change Point Regime", "regime_state", "ruptures-bayes", "structural break detection", ["15m", "1h", "4h"], ["returns", "volume", "oi"], "hourly", "Detects sudden market structure shifts before classifiers drift", "phase_2"),
    _entry("regime_gmm_liquidity", "Gaussian Mixture Liquidity State", "regime_state", "sklearn-gmm", "market micro-regime clustering", ["5m", "15m", "1h"], ["spread", "depth", "volume"], "hourly", "Separates liquid continuation from thin reflexive chop", "phase_3"),
    _entry("regime_variational_encoder", "Variational Regime Encoder", "regime_state", "pytorch-vae", "unsupervised latent regime discovery", ["1h", "4h", "1d"], ["multi_source_sequences"], "daily", "Finds non-obvious latent states for expert routing", "phase_4"),
    # Microstructure and event engines
    _entry("micro_hawkes_flow", "Hawkes Flow Excitation", "microstructure", "hawkes", "event intensity forecasting", ["1m", "5m", "15m"], ["trades", "liquidations", "orderflow"], "15m", "Models self-exciting bursts before pumps and squeezes", "phase_3"),
    _entry("micro_orderbook_imbalance", "Order Book Imbalance Classifier", "microstructure", "lightgbm", "short-horizon move classification", ["1m", "5m", "15m"], ["depth", "spread", "microprice"], "5m", "Pushes exactness on execution-sensitive short horizons", "phase_2"),
    _entry("micro_liquidation_cascade", "Liquidation Cascade Detector", "microstructure", "xgboost", "cascade probability classification", ["5m", "15m", "1h"], ["liquidations", "oi", "funding"], "15m", "Flags asymmetry when leverage unwind risk dominates", "phase_2"),
    _entry("micro_vpvr_levels", "VPVR Level Ranker", "microstructure", "lambda-mart", "support/resistance ranking", ["15m", "1h", "4h"], ["volume_profile", "market_structure"], "hourly", "Improves exact target placement around high-volume nodes", "phase_3"),
    _entry("micro_autoencoder_volume_spike", "Volume Spike Autoencoder", "microstructure", "pytorch-autoencoder", "anomaly detection", ["1m", "5m", "15m"], ["volume_sequences", "trade_counts"], "15m", "Separates genuine breakout participation from noise", "phase_2"),
    _entry("micro_refined_cusum", "Refined CUSUM Event Model", "microstructure", "cusum-plus-features", "pump/dump event detection", ["1m", "5m", "15m"], ["returns", "volume", "baseline_drift"], "15m", "Keeps ultra-fast manipulation detection cheap and explainable", "phase_1", "active"),
    # Narrative and sentiment
    _entry("nlp_crypto_finbert", "Crypto FinBERT Sentiment", "narrative_sentiment", "transformers-finbert", "headline/body sentiment classification", ["1h", "4h", "1d"], ["news", "social_posts"], "6h", "Domain-tuned sentiment signal for event-driven moves", "phase_2"),
    _entry("nlp_deberta_impact", "DeBERTa Headline Impact", "narrative_sentiment", "transformers-deberta", "impact classification", ["1h", "4h", "1d"], ["news", "token_context"], "6h", "Estimates whether a headline matters, not just polarity", "phase_2"),
    _entry("nlp_bertopic", "BERTopic Narrative Clusters", "narrative_sentiment", "bertopic", "topic discovery", ["4h", "1d", "7d"], ["news_corpus", "social_corpus"], "daily", "Surfaces emergent narratives before they show up in price", "phase_3"),
    _entry("nlp_event_extractor", "Market Event Extractor", "narrative_sentiment", "transformers-seq2seq", "structured event extraction", ["1h", "4h", "1d"], ["news", "calendar", "governance_posts"], "6h", "Turns raw text into discrete catalysts for exactness layers", "phase_3"),
    _entry("nlp_cross_source_gnn", "Cross-Source Influence Graph", "narrative_sentiment", "graph-neural-network", "propagation scoring", ["4h", "1d"], ["news", "social", "onchain_mentions"], "daily", "Measures whether a narrative is spreading into tradable attention", "phase_4"),
    _entry("nlp_regulatory_stance", "Regulatory Stance Classifier", "narrative_sentiment", "transformers-roberta", "stance classification", ["1d", "7d"], ["regulatory_text"], "daily", "Specialized model for one of the highest-impact catalyst classes", "phase_3"),
    _entry("nlp_source_reliability", "Source Reliability Ranker", "narrative_sentiment", "xgboost", "source quality ranking", ["1h", "4h", "1d"], ["publisher_history", "engagement", "correction_rate"], "daily", "Discounts low-quality narratives before they pollute ensembles", "phase_2"),
    # On-chain and fundamentals
    _entry("onchain_tvl_factor", "TVL Factor Model", "onchain_fundamental", "xgboost", "fundamental momentum regression", ["1d", "7d"], ["tvl", "revenue", "fees", "users"], "daily", "Provides slower fundamental anchor for swing predictions", "phase_2"),
    _entry("onchain_exchange_flow", "Exchange Flow Classifier", "onchain_fundamental", "xgboost", "flow direction classification", ["1h", "4h", "1d"], ["exchange_flows", "whale_transfers"], "hourly", "Measures accumulation versus distribution pressure", "phase_2"),
    _entry("onchain_active_address_residual", "Active Address Residual Model", "onchain_fundamental", "lightgbm", "valuation residual regression", ["1d", "7d"], ["active_addresses", "price", "volume"], "daily", "Finds divergence between price and network usage", "phase_3"),
    _entry("onchain_mvrv_nvt", "MVRV/NVT Valuation Residual", "onchain_fundamental", "elasticnet-plus-xgb", "valuation residual regression", ["1d", "7d"], ["mvrv", "nvt", "supply_dynamics"], "daily", "Tighter medium-horizon fair-value estimates for BTC majors", "phase_2"),
    _entry("onchain_stablecoin_liquidity", "Stablecoin Liquidity Model", "onchain_fundamental", "lightgbm", "risk-on liquidity scoring", ["4h", "1d", "7d"], ["stablecoin_supply", "flows", "dominance"], "6h", "Captures deployable buying power before spot rotation", "phase_3"),
    _entry("onchain_cycle_composite", "Cycle Composite Fair Value", "onchain_fundamental", "ensemble-composite", "cycle phase and fair value estimation", ["1d", "7d"], ["halving", "hashrate", "mvrv", "nvt"], "daily", "Improves exact swing targets by anchoring them to cycle context", "phase_1", "active"),
    # Risk and security
    _entry("risk_rug_xgboost", "Calibrated Rug XGBoost", "risk_security", "xgboost", "rug probability classification", ["event"], ["bytecode", "holder_distribution", "taxes"], "daily", "Cleaner risk gating before any automated long bias", "phase_2"),
    _entry("risk_bytecode_autoencoder", "Bytecode Autoencoder", "risk_security", "pytorch-autoencoder", "contract anomaly detection", ["event"], ["opcode_features", "selector_entropy"], "daily", "Detects novel malicious bytecode patterns beyond rules", "phase_3"),
    _entry("risk_wallet_behavior_transformer", "Wallet Behavior Transformer", "risk_security", "pytorch-transformer", "wallet role classification", ["event"], ["transaction_sequences", "counterparty_graph"], "daily", "Separates smart money from spoofing and wash behavior", "phase_3"),
    _entry("risk_honeypot_calibrator", "Honeypot Probability Calibrator", "risk_security", "isotonic-plus-xgboost", "honeypot probability calibration", ["event"], ["swap_failures", "taxes", "sellability"], "daily", "Reduces false positives in token safety gates", "phase_2"),
    _entry("risk_contract_graph", "Contract Graph Risk Model", "risk_security", "graph-neural-network", "entity risk propagation", ["event"], ["contract_graph", "deployer_graph", "wallet_graph"], "daily", "Captures ecosystem-level contamination and related rugs", "phase_4"),
    # Meta ensemble and control plane
    _entry("meta_stacking", "Stacking Meta Learner", "meta_ensemble", "logistic-regression-plus-trees", "ensemble blending", ["15m", "1h", "4h", "1d"], ["base_model_outputs", "regime", "confidence"], "hourly", "Learns which base model to trust in each context", "phase_1"),
    _entry("meta_bayesian_model_averaging", "Bayesian Model Averaging", "meta_ensemble", "bayesian", "probability blending", ["1h", "4h", "1d"], ["base_model_outputs", "historical_accuracy"], "hourly", "Smooths overfitting and improves calibrated ensemble probability", "phase_2"),
    _entry("meta_isotonic", "Isotonic Probability Calibrator", "meta_ensemble", "sklearn-isotonic", "probability calibration", ["15m", "1h", "4h", "1d"], ["prediction_outcomes"], "hourly", "Turns confidence into something operationally trustworthy", "phase_1", "active"),
    _entry("meta_temperature_scaling", "Temperature Scaling Calibrator", "meta_ensemble", "temperature-scaling", "logit calibration", ["15m", "1h", "4h"], ["classification_logits"], "hourly", "Cheap calibration layer for neural classifiers", "phase_2"),
    _entry("meta_drift_detector", "PSI/KS Drift Detector", "meta_ensemble", "drift-monitor", "distribution shift detection", ["all"], ["feature_distributions", "prediction_errors"], "hourly", "Protects exactness by downgrading stale models automatically", "phase_1"),
    _entry("meta_champion_challenger", "Champion-Challenger Router", "meta_ensemble", "policy-engine", "online promotion routing", ["all"], ["benchmarks", "latency", "accuracy"], "hourly", "Operational engine for safe rollout of 50+ model candidates", "phase_1"),
    _entry("meta_residual_corrector", "Residual Error Corrector", "meta_ensemble", "lightgbm", "residual correction regression", ["1h", "4h", "1d"], ["ensemble_outputs", "recent_errors"], "hourly", "Shrinks repeated target bias without replacing the whole stack", "phase_2"),
    _entry("meta_policy_bandit", "Policy Bandit Model Router", "meta_ensemble", "contextual-bandit", "adaptive model selection", ["15m", "1h", "4h", "1d"], ["regime", "asset_type", "recent_scores"], "hourly", "Routes symbols and horizons toward the current best expert", "phase_3"),
]


ROADMAP_PHASES = [
    {
        "phase": "phase_0_foundation",
        "duration": "1-2 weeks",
        "focus": "repair the training plumbing before adding more models",
        "deliverables": [
            "unify train/retrain payload contracts",
            "fix workflow port and endpoint mismatches",
            "make model artifact volume writable",
            "standardize artifact naming and model reload behavior",
            "replace synthetic training placeholders with real dataset adapters",
        ],
    },
    {
        "phase": "phase_1_production_baseline",
        "duration": "2-4 weeks",
        "focus": "establish a stable exactness baseline around direction, targets, and calibration",
        "deliverables": [
            "direction_xgb_* trio as production backbone",
            "target_xgb_quantile plus conformal intervals",
            "stacking meta learner with isotonic calibration",
            "drift detector and champion-challenger routing",
            "benchmark suite for latency, hit rate, and calibration error",
        ],
    },
    {
        "phase": "phase_2_benchmark_matrix",
        "duration": "4-8 weeks",
        "focus": "run 20+ challenger models against walk-forward and asset-segmented benchmarks",
        "deliverables": [
            "tree-based challengers across direction and targets",
            "microstructure specialists for short horizons",
            "fundamental and narrative challengers for swing horizons",
            "per-horizon promotion gates using Brier score, MAE, and interval coverage",
        ],
    },
    {
        "phase": "phase_3_sequence_and_probabilistic",
        "duration": "8-12 weeks",
        "focus": "introduce sequence models where they beat tabular baselines by clear margins",
        "deliverables": [
            "N-BEATS, N-HiTS, TFT, DeepAR, transformer encoders",
            "probabilistic target distributions instead of point-only targets",
            "specialized regulatory and catalyst NLP models",
            "state-aware routers for regime-conditioned ensembles",
        ],
    },
    {
        "phase": "phase_4_online_learning_control_plane",
        "duration": "12+ weeks",
        "focus": "close the loop with live learning, residual correction, and safe promotion",
        "deliverables": [
            "policy bandit routing",
            "residual correctors trained on recent model bias",
            "cross-source influence graphs and graph risk models",
            "automated rollback on calibration drift or latency regression",
        ],
    },
]


def get_model_catalog() -> dict:
    counts = Counter(model["category"] for model in MODEL_CATALOG)
    phase_counts = Counter(model["rollout_phase"] for model in MODEL_CATALOG)

    return {
        "generated_at": "static",
        "total_models": len(MODEL_CATALOG),
        "category_counts": dict(sorted(counts.items())),
        "phase_counts": dict(sorted(phase_counts.items())),
        "models": MODEL_CATALOG,
    }


def get_training_roadmap() -> dict:
    return {
        "objective": "increase prediction exactness through decomposition, calibration, and champion-challenger routing",
        "principles": [
            "Exact predictions are probabilistic; improve exactness by separating direction, magnitude, interval, and confidence calibration.",
            "Do not promote a new model until it wins on walk-forward accuracy, calibration, latency, and stability together.",
            "Short horizons need microstructure specialists; long horizons need macro, on-chain, and narrative context.",
            "Retraining without drift checks and artifact hygiene degrades the system faster than adding more models helps it.",
        ],
        "success_metrics": [
            "directional hit rate by horizon and asset bucket",
            "Brier score and expected calibration error",
            "MAE and MAPE for target deltas",
            "interval coverage versus target width",
            "latency budget adherence per model family",
            "promotion win rate in champion-challenger tests",
        ],
        "recommended_backbone": [
            "direction_xgb_scalp",
            "direction_xgb_standard",
            "direction_xgb_position",
            "target_xgb_quantile",
            "interval_conformal_calibrator",
            "meta_stacking",
            "meta_isotonic",
            "meta_drift_detector",
        ],
        "phases": ROADMAP_PHASES,
        "catalog_summary": get_model_catalog(),
    }
