#!/usr/bin/env python3
"""
ml_feedback.py — API routes pour le feedback loop ML (turf_saas).

Routes:
  POST /api/v1/ml/feedback/run   — Déclenche le feedback loop (admin uniquement)
  GET  /api/v1/ml/feedback/stats — Stats performances par stratégie

Sécurité admin : token via variable d'environnement ML_ADMIN_TOKEN
ou plan "pro" en fallback pour les stats.
"""

import os
import sys
from datetime import datetime

from flask import Blueprint, jsonify, request, g

# Ajoute le répertoire parent de api_v1 dans le path pour importer ml_feedback_saas
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))

from api_v1.utils import get_db, internal_error, bad_request
# Auth: try flask_jwt_extended (app_v1) first, fall back to saas_auth (portal_server)
try:
    from auth import jwt_required_middleware
except ImportError:
    from saas_auth import require_auth as jwt_required_middleware
try:
    from auth import plan_required
except ImportError:
    plan_required = lambda *a, **kw: (lambda f: f)

ml_feedback_bp = Blueprint("v1_ml_feedback", __name__, url_prefix="/api/v1/ml/feedback")

# Token admin interne — configurable via variable d'environnement
ML_ADMIN_TOKEN = os.environ.get("ML_ADMIN_TOKEN", "")


def _check_admin(req):
    """Vérifie le token admin via header X-Admin-Token ou Authorization Bearer (plan pro)."""
    # 1. Token interne (scheduler/cron)
    admin_token = req.headers.get("X-Admin-Token", "").strip()
    if ML_ADMIN_TOKEN and admin_token == ML_ADMIN_TOKEN:
        return True, None

    # 2. Pas de token admin configuré → autoriser les utilisateurs "pro" authentifiés
    user = getattr(request, "current_user", None) or getattr(g, "current_user", None)
    if user and user.get("plan") == "pro":
        return True, None

    return False, jsonify({"error": "Accès admin requis", "code": 403}), 403


@ml_feedback_bp.route("/run", methods=["POST"])
@jwt_required_middleware
def feedback_run():
    """
    Déclenche le feedback loop ML pour une date donnée.
    ---
    tags:
      - ML Feedback
    summary: Déclenche le feedback loop XGBoost (admin only)
    security:
      - Bearer: []
      - AdminToken: []
    parameters:
      - name: body
        in: body
        schema:
          type: object
          properties:
            date:
              type: string
              description: Date YYYY-MM-DD (défaut aujourd'hui)
              example: "2026-04-25"
            mode:
              type: string
              description: "run (défaut) ou backfill"
              enum: [run, backfill]
              example: run
    responses:
      200:
        description: Feedback loop exécuté avec succès
      400:
        description: Paramètre invalide
      403:
        description: Accès refusé
      500:
        description: Erreur interne
    """
    # Vérification admin
    user = getattr(request, "current_user", None) or getattr(g, "current_user", None)
    admin_token = request.headers.get("X-Admin-Token", "").strip()
    is_admin = (ML_ADMIN_TOKEN and admin_token == ML_ADMIN_TOKEN) or (
        user and user.get("plan") == "pro"
    )
    if not is_admin:
        return jsonify({"error": "Accès admin requis", "code": 403}), 403

    body = request.get_json(silent=True) or {}
    date_str = body.get("date") or datetime.now().strftime("%Y-%m-%d")
    mode = body.get("mode", "run")

    # Validation date
    try:
        datetime.strptime(date_str, "%Y-%m-%d")
    except ValueError:
        return bad_request(f"Date invalide : {date_str}. Format attendu : YYYY-MM-DD")

    if mode not in ("run", "backfill"):
        return bad_request("mode doit être 'run' ou 'backfill'")

    try:
        import ml_feedback_saas

        if mode == "backfill":
            inseres, maj = ml_feedback_saas.backfill(date_str)
            total_inseres = inseres
        else:
            result = ml_feedback_saas.run(date_str)
            total_inseres = sum(result["inseres"].values())
            maj = result["maj"]

        return jsonify(
            {
                "status": "ok",
                "date": date_str,
                "mode": mode,
                "paris_inseres": total_inseres,
                "paris_mis_a_jour": maj,
            }
        ), 200

    except Exception as e:
        return internal_error(str(e))


@ml_feedback_bp.route("/stats", methods=["GET"])
@jwt_required_middleware
@plan_required("premium", "pro")
def feedback_stats():
    """
    Stats performances ML par stratégie.
    ---
    tags:
      - ML Feedback
    summary: Stats paris ML par stratégie (premium+)
    security:
      - Bearer: []
    parameters:
      - name: date_debut
        in: query
        type: string
        description: Date de début YYYY-MM-DD
      - name: date_fin
        in: query
        type: string
        description: Date de fin YYYY-MM-DD
    responses:
      200:
        description: Stats par stratégie
      401:
        description: Token invalide
      403:
        description: Plan insuffisant (premium ou pro requis)
    """
    date_debut = request.args.get("date_debut")
    date_fin = request.args.get("date_fin")

    # Validation optionnelle des dates
    for d_str, label in [(date_debut, "date_debut"), (date_fin, "date_fin")]:
        if d_str:
            try:
                datetime.strptime(d_str, "%Y-%m-%d")
            except ValueError:
                return bad_request(f"{label} invalide : {d_str}. Format : YYYY-MM-DD")

    conn = get_db()
    try:
        import ml_feedback_saas

        stats = ml_feedback_saas.get_feedback_stats(conn, date_debut, date_fin)

        return jsonify(
            {
                "status": "ok",
                "strategies": stats,
                "filters": {
                    "date_debut": date_debut,
                    "date_fin": date_fin,
                },
                "total_strategies": len(stats),
            }
        ), 200

    except Exception as e:
        return internal_error(str(e))
    finally:
        conn.close()
