#!/usr/bin/env python3
"""
SaaS API v1 Blueprint — /api/v1/*
Stats, prédictions, résumés pour le dashboard SaaS.
Sprint 4-5 — HRT-30
"""

from flask import Blueprint, request, jsonify
import sqlite3
import os
from datetime import datetime
from saas_auth import require_auth

DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db")

api_v1_bp = Blueprint("api_v1", __name__, url_prefix="/api/v1")


def get_db():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def plan_allows(user_plan: str, required: str) -> bool:
    order = {"free": 0, "premium": 1, "pro": 2}
    return order.get(user_plan, 0) >= order.get(required, 0)


# ─── Stats ────────────────────────────────────────────────────────────────────


@api_v1_bp.route("/stats/summary", methods=["GET"])
@require_auth
def stats_summary():
    """GET /api/v1/stats/summary — résumé dashboard."""
    today = datetime.now().strftime("%Y-%m-%d")
    conn = get_db()

    try:
        # Courses today
        courses_today = (
            conn.execute(
                "SELECT COUNT(DISTINCT num_reunion||'-'||num_course) FROM ml_predictions_cache WHERE date=?",
                (today,),
            ).fetchone()[0]
            or 0
        )

        # Value bets today
        value_bets_today = (
            conn.execute(
                "SELECT COUNT(*) FROM ml_predictions_cache WHERE date=? AND is_value_bet=1",
                (today,),
            ).fetchone()[0]
            or 0
        )

        # Accuracy top3 (30 days)
        acc_row = conn.execute("""
            SELECT
                CAST(SUM(CASE WHEN p.ordre_arrivee BETWEEN 1 AND 3 AND m.recommendation='top3' THEN 1 ELSE 0 END) AS FLOAT)
                / NULLIF(COUNT(CASE WHEN m.recommendation='top3' THEN 1 END), 0) * 100 AS acc
            FROM ml_predictions_cache m
            JOIN pmu_partants p ON m.horse_name=p.nom AND m.date=p.date_programme
            WHERE m.date >= date('now', '-30 days')
        """).fetchone()
        accuracy_top3 = round(acc_row[0], 1) if acc_row and acc_row[0] else None

        # Next race
        next_race = conn.execute(
            "SELECT heure, hippodrome FROM ml_predictions_cache WHERE date=? AND heure IS NOT NULL ORDER BY heure LIMIT 1",
            (today,),
        ).fetchone()

        conn.close()
        return jsonify(
            {
                "courses_today": courses_today,
                "value_bets_today": value_bets_today,
                "accuracy_top3": accuracy_top3,
                "next_race_time": next_race["heure"] if next_race else None,
                "next_race_hippodrome": next_race["hippodrome"] if next_race else None,
            }
        ), 200

    except Exception as e:
        conn.close()
        return jsonify(
            {"error": str(e), "courses_today": 0, "value_bets_today": 0}
        ), 200


# ─── Predictions ──────────────────────────────────────────────────────────────


@api_v1_bp.route("/predictions/today", methods=["GET"])
@require_auth
def predictions_today():
    """GET /api/v1/predictions/today — prédictions du jour selon le plan."""
    user = request.current_user
    plan = user.get("plan", "free")
    today = datetime.now().strftime("%Y-%m-%d")
    conn = get_db()

    try:
        rows = conn.execute(
            """
            SELECT horse_name, horse_number, odds, prob_top1, prob_top3,
                   ml_score, recommendation, is_value_bet, is_outlier,
                   race_label, race_name, hippodrome, discipline, distance,
                   heure, risque_label, risque_score, num_reunion, num_course
            FROM ml_predictions_cache
            WHERE date=?
            ORDER BY num_reunion, num_course, ml_score DESC
        """,
            (today,),
        ).fetchall()
        conn.close()

        predictions = [dict(r) for r in rows]

        # Free plan: return only 1 race
        if plan == "free":
            if predictions:
                first = predictions[0]
                first_key = (first["num_reunion"], first["num_course"])
                predictions = [
                    p
                    for p in predictions
                    if (p["num_reunion"], p["num_course"]) == first_key
                ]
                # Mask value bet flag in free
                for p in predictions:
                    p["is_value_bet"] = 0

        # Premium/Pro: full predictions
        return jsonify(
            {
                "date": today,
                "plan": plan,
                "count": len(predictions),
                "predictions": predictions,
            }
        ), 200

    except Exception as e:
        conn.close()
        return jsonify({"error": str(e), "predictions": []}), 200


@api_v1_bp.route("/predictions/race/<race_label>", methods=["GET"])
@require_auth
def predictions_race(race_label):
    """GET /api/v1/predictions/race/<label> — prédictions d'une course."""
    user = request.current_user
    plan = user.get("plan", "free")
    today = datetime.now().strftime("%Y-%m-%d")

    # Parse label like R1C3 → num_reunion=1, num_course=3
    import re

    m = re.match(r"R(\d+)C(\d+)", race_label.upper())
    if not m:
        return jsonify({"error": "Format invalide, attendu: R{n}C{n}"}), 400
    nr, nc = int(m.group(1)), int(m.group(2))

    conn = get_db()
    rows = conn.execute(
        """
        SELECT * FROM ml_predictions_cache
        WHERE date=? AND num_reunion=? AND num_course=?
        ORDER BY ml_score DESC
    """,
        (today, nr, nc),
    ).fetchall()
    conn.close()

    predictions = [dict(r) for r in rows]
    if plan == "free" and predictions:
        # Only show first race
        pass  # allowed in detail view if they know the race label

    return jsonify({"predictions": predictions, "count": len(predictions)}), 200


# ─── Value Bets ───────────────────────────────────────────────────────────────


@api_v1_bp.route("/value-bets/today", methods=["GET"])
@require_auth
def value_bets_today():
    """GET /api/v1/value-bets/today — value bets (Premium+)."""
    user = request.current_user
    plan = user.get("plan", "free")
    if not plan_allows(plan, "premium"):
        return jsonify(
            {
                "error": "Cette fonctionnalité requiert un plan Premium ou Pro.",
                "upgrade_required": True,
            }
        ), 403

    today = datetime.now().strftime("%Y-%m-%d")
    conn = get_db()
    rows = conn.execute(
        """
        SELECT horse_name, race_label, race_name, hippodrome, odds,
               prob_top3, ml_score, risque_label, heure
        FROM ml_predictions_cache
        WHERE date=? AND is_value_bet=1
        ORDER BY ml_score DESC
    """,
        (today,),
    ).fetchall()
    conn.close()
    return jsonify({"value_bets": [dict(r) for r in rows], "count": len(rows)}), 200


# ─── Export ───────────────────────────────────────────────────────────────────


@api_v1_bp.route("/export/csv", methods=["GET"])
@require_auth
def export_csv():
    """GET /api/v1/export/csv — export CSV (Pro only)."""
    from flask import Response
    import csv, io

    user = request.current_user
    plan = user.get("plan", "free")
    if not plan_allows(plan, "pro"):
        return jsonify(
            {"error": "L'export CSV requiert un plan Pro.", "upgrade_required": True}
        ), 403

    date_param = request.args.get("date", datetime.now().strftime("%Y-%m-%d"))
    conn = get_db()
    rows = conn.execute(
        "SELECT * FROM ml_predictions_cache WHERE date=? ORDER BY num_reunion, num_course, ml_score DESC",
        (date_param,),
    ).fetchall()
    conn.close()

    output = io.StringIO()
    if rows:
        writer = csv.DictWriter(output, fieldnames=rows[0].keys())
        writer.writeheader()
        writer.writerows([dict(r) for r in rows])

    return Response(
        output.getvalue(),
        mimetype="text/csv",
        headers={
            "Content-Disposition": f"attachment; filename=turf_ia_{date_param}.csv"
        },
    )


# ─── Billing Blueprint (Stripe) + JWT init — HRT-49 ─────────────────────────
# Registers /api/v1/billing/* routes via nested Blueprint (Flask 2.0+)
# Also initializes JWTManager on the Flask app (required for jwt_required_middleware)
try:
    from flask_jwt_extended import JWTManager
    from api_v1.routes.billing import billing_bp

    # Initialize JWTManager on the Flask app when api_v1_bp is registered
    @api_v1_bp.record_once
    def _init_jwt(state):
        app = state.app
        if not app.config.get('JWT_SECRET_KEY'):
            import os
            app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET_KEY', 'turf-saas-secret-key-change-in-prod')
        if 'flask_jwt_extended' not in app.extensions:
            JWTManager(app)

    # Register billing blueprint with url_prefix='/billing'
    # (parent api_v1_bp has '/api/v1', so result is /api/v1/billing/*)
    api_v1_bp.register_blueprint(billing_bp, url_prefix='/billing')
    print('[saas_api_v1] Billing blueprint (Stripe) + JWT registered ✅')
except Exception as _billing_err:
    print(f'[saas_api_v1] Warning: billing blueprint not loaded: {_billing_err}')
