#!/usr/bin/env python3
"""
Turf SaaS API v1 — Auth JWT + Multi-tenant
Sprint 2-3: HRT-28

Run:
    FLASK_ENV=development ./venv/bin/python saas_api.py

Ports (isolated from production):
  Portal:       8793
  SaaS API:     8792   ← this file
  Dashboard:    8791
  Combined API: 8790
"""

import os
import logging
import logging.handlers
import sys

from flask import Flask, jsonify, g, request
from flask_cors import CORS
from flask_jwt_extended import JWTManager, get_jwt

from auth_db import init_auth_tables
from auth import (
    auth_bp,
    jwt_required_middleware,
    plan_required,
    free_daily_limit_check,
    _get_user_by_id,
)
from middleware import rate_limit_middleware, access_log_middleware

# ──────────────────────────────────────────────────────────────
# Logging setup
# ──────────────────────────────────────────────────────────────

LOG_DIR = os.path.join(os.path.dirname(__file__), "logs")
os.makedirs(LOG_DIR, exist_ok=True)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.handlers.RotatingFileHandler(
            os.path.join(LOG_DIR, "saas_api.log"),
            maxBytes=5 * 1024 * 1024,
            backupCount=3,
        ),
    ],
)

# ──────────────────────────────────────────────────────────────
# App factory
# ──────────────────────────────────────────────────────────────


def create_app(test_config=None):
    app = Flask(__name__)

    # JWT config
    app.config["JWT_SECRET_KEY"] = os.environ.get(
        "JWT_SECRET_KEY", "CHANGE_ME_IN_PRODUCTION_" + os.urandom(24).hex()
    )
    app.config["JWT_ACCESS_TOKEN_EXPIRES"] = 900  # 15 minutes
    app.config["JWT_REFRESH_TOKEN_EXPIRES"] = 2592000  # 30 days

    if test_config:
        app.config.update(test_config)

    # CORS — SaaS domain + localhost for dev
    CORS(
        app,
        origins=os.environ.get(
            "CORS_ORIGINS",
            "http://localhost:8793,http://127.0.0.1:8793,https://turf-ia.h3r7.tech",
        ).split(","),
        methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
        allow_headers=["Content-Type", "Authorization"],
        supports_credentials=True,
    )

    # JWT
    jwt = JWTManager(app)

    # ── JWT error handlers ────────────────────────────────────
    @jwt.expired_token_loader
    def expired_token(_jwt_header, _jwt_payload):
        return jsonify({"error": "Token expiré"}), 401

    @jwt.invalid_token_loader
    def invalid_token(reason):
        return jsonify({"error": "Token invalide", "detail": reason}), 422

    @jwt.unauthorized_loader
    def unauthorized(reason):
        return jsonify({"error": "Token manquant ou invalide", "detail": reason}), 401

    # ── Register middleware ───────────────────────────────────
    rate_limit_middleware(app)
    access_log_middleware(app)

    # ── Blueprints ────────────────────────────────────────────
    app.register_blueprint(auth_bp)

    # ── Predictions routes (multi-tenant plan check) ──────────

    @app.route("/api/v1/predictions", methods=["GET"])
    @jwt_required_middleware
    @free_daily_limit_check
    def predictions():
        """
        GET /api/v1/predictions
        - free:    Top 3 uniquement (déjà filtrées par le moteur ML)
        - premium: toutes courses + alertes Telegram
        - pro:     API complète + export CSV disponible
        """
        user = g.current_user
        plan = user["plan"]

        # Forward to combined_api for actual predictions
        import requests as req

        try:
            params = dict(request.args)
            resp = req.get(
                "http://localhost:8790/api/predictions",
                params=params,
                timeout=10,
            )
            data = resp.json()
        except Exception as e:
            return jsonify(
                {"error": "Service prédictions indisponible", "detail": str(e)}
            ), 503

        # Plan filtering
        if plan == "free":
            # Top 3 only
            if isinstance(data, list):
                data = [
                    {k: v for k, v in p.items() if k not in ("score_detaille",)}
                    for p in data[:3]
                ]
            return jsonify({"plan": plan, "predictions": data, "limit": "Top 3"}), 200

        elif plan == "premium":
            # All courses, but no CSV export
            return jsonify(
                {"plan": plan, "predictions": data, "telegram_alerts": True}
            ), 200

        else:  # pro
            return jsonify(
                {
                    "plan": plan,
                    "predictions": data,
                    "telegram_alerts": True,
                    "csv_export_url": "/api/v1/predictions/export",
                }
            ), 200

    @app.route("/api/v1/predictions/export", methods=["GET"])
    @jwt_required_middleware
    @plan_required("pro")
    def predictions_export():
        """CSV export — pro plan only."""
        import requests as req
        import io

        try:
            resp = req.get(
                "http://localhost:8790/api/predictions/export",
                params=dict(request.args),
                timeout=15,
            )
            from flask import Response

            return Response(
                resp.content,
                mimetype="text/csv",
                headers={"Content-Disposition": "attachment; filename=predictions.csv"},
            )
        except Exception as e:
            return jsonify({"error": "Export indisponible", "detail": str(e)}), 503

    @app.route("/api/v1/subscription/upgrade", methods=["GET"])
    @jwt_required_middleware
    def subscription_info():
        """Return available plans and current user plan."""
        user = g.current_user
        return jsonify(
            {
                "current_plan": user["plan"],
                "plans": {
                    "free": {
                        "price": "0€/mois",
                        "features": ["Top 3 prédictions", "1 course/jour"],
                    },
                    "premium": {
                        "price": "9.99€/mois",
                        "features": [
                            "Toutes les courses",
                            "Alertes Telegram",
                            "Historique 30j",
                        ],
                    },
                    "pro": {
                        "price": "29.99€/mois",
                        "features": [
                            "API complète",
                            "Export CSV",
                            "Alertes Telegram",
                            "Historique illimité",
                            "Support prioritaire",
                        ],
                    },
                },
                "upgrade_contact": "contact@h3r7.tech",
            }
        ), 200

    # ── Health check ──────────────────────────────────────────

    @app.route("/api/v1/health", methods=["GET"])
    def health():
        return jsonify(
            {"status": "ok", "service": "turf-saas-api", "version": "2.3.0"}
        ), 200

    # Init DB tables on startup
    with app.app_context():
        init_auth_tables()

    return app


# ──────────────────────────────────────────────────────────────
# Entrypoint
# ──────────────────────────────────────────────────────────────

if __name__ == "__main__":
    app = create_app()
    port = int(os.environ.get("SAAS_API_PORT", 8792))
    app.run(host="0.0.0.0", port=port, debug=False)
