"""Application FastAPI principale."""
import json
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime

# #region agent log
def write_debug_log(hypothesisId: str, location: str, message: str, data: dict = None):
    """Écrit un log NDJSON pour le debug."""
    log_entry = {
        "sessionId": "debug-session",
        "runId": "run1",
        "hypothesisId": hypothesisId,
        "location": location,
        "message": message,
        "data": data or {},
        "timestamp": datetime.now().timestamp() * 1000
    }
    with open(r"d:\\dev_new_pc\\chartbastan\\.cursor\\debug.log", "a") as f:
        f.write(json.dumps(log_entry) + "\n")
# #endregion

app = FastAPI(
    title="Chartbastan API",
    description="""
    API publique pour les prédictions de matchs basées sur l'énergie collective.

    ## Endpoints Publics
    - **Prédictions**: Accès aux prédictions de matchs avec filtres
    - **Matchs**: Liste des matchs avec filtres par ligue et statut

    ## Authentification
    Les endpoints publics ne nécessitent pas d'authentification.
    Pour un usage intensif, générez une clé API via le dashboard développeur.
    """,
    version="1.0.0",
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json"
)

# #region agent log
write_debug_log("A", "main.py:1", "FastAPI app initialized", {"app_title": "Chartbastan API"})
# #endregion

# Rate limiting middleware DÉSACTIVÉ PERMANENTMENT
# app.add_middleware(RateLimitMiddleware, public_limit=10, authenticated_limit=100)

# #region agent log
write_debug_log("E", "main.py:27", "RateLimitMiddleware DISABLED permanently", {"status": "disabled"})
# #endregion

# CORS configuration
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allow all origins for public API
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# #region agent log
write_debug_log("E", "main.py:35", "CORSMiddleware configured", {"allow_origins": ["*"], "allow_methods": ["*"], "allow_headers": ["*"]})
# #endregion

@app.middleware("http")
async def log_requests(request: Request, call_next):
    """Log toutes les requêtes entrantes pour diagnostic."""
    start_time = datetime.now()
    write_debug_log("A", "main.py:44", "Incoming request", {
        "method": request.method,
        "url": str(request.url),
        "path": request.url.path,
        "headers": dict(request.headers)
    })
    response = await call_next(request)
    process_time = (datetime.now() - start_time).total_seconds()
    write_debug_log("A", "main.py:44", "Request completed", {
        "method": request.method,
        "url": str(request.url),
        "path": request.url.path,
        "status_code": response.status_code,
        "process_time": process_time
    })
    return response

@app.get("/")
def read_root():
    """Endpoint racine de l'API."""
    write_debug_log("A", "main.py:58", "Root endpoint called", {"path": "/"})
    return {"message": "Chartbastan API"}

@app.get("/health")
def health_check():
    """Endpoint de vérification de santé."""
    return {"status": "healthy"}


# ============================================================
# AUTH ENDPOINTS - Définis directement ici pour garantir l'enregistrement
# ============================================================
from fastapi import Depends, HTTPException, status
from sqlalchemy.orm import Session
from pydantic import BaseModel, EmailStr
from typing import Optional
from passlib.context import CryptContext

from app.database import get_db
from app.models.user import User

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


class LoginRequest(BaseModel):
    email: EmailStr
    password: str


class RegisterRequest(BaseModel):
    email: EmailStr
    password: str
    name: Optional[str] = None
    referral_code: Optional[str] = None


def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)


def get_password_hash(password: str) -> str:
    return pwd_context.hash(password)


@app.post("/api/v1/auth/login")
def login_user(request: LoginRequest, db: Session = Depends(get_db)):
    """Connecter un utilisateur."""
    user = db.query(User).filter(User.email == request.email).first()
    
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Email ou mot de passe incorrect"
        )
    
    if not user.password_hash:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Email ou mot de passe incorrect"
        )
    
    if not verify_password(request.password, user.password_hash):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Email ou mot de passe incorrect"
        )
    
    return {
        "data": {
            "id": user.id,
            "email": user.email,
            "name": user.name,
            "is_premium": user.is_premium,
            "referral_code": user.referral_code,
            "created_at": str(user.created_at),
        },
        "meta": {
            "timestamp": datetime.utcnow().isoformat(),
            "version": "v1"
        }
    }


@app.post("/api/v1/auth/register", status_code=status.HTTP_201_CREATED)
def register_user(request: RegisterRequest, db: Session = Depends(get_db)):
    """Inscrire un nouvel utilisateur."""
    import secrets
    import string
    
    existing_user = db.query(User).filter(User.email == request.email).first()
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="Cet email est déjà utilisé"
        )
    
    # Générer code de parrainage
    alphabet = string.ascii_uppercase + string.digits
    referral_code = ''.join(secrets.choice(alphabet) for _ in range(8))
    
    password_hash = get_password_hash(request.password)
    
    new_user = User(
        email=request.email,
        password_hash=password_hash,
        name=request.name,
        is_premium=False,
        referral_code=referral_code,
        created_at=datetime.utcnow(),
        updated_at=datetime.utcnow()
    )
    
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    
    return {
        "data": {
            "id": new_user.id,
            "email": new_user.email,
            "name": new_user.name,
            "is_premium": new_user.is_premium,
            "referral_code": new_user.referral_code,
            "created_at": str(new_user.created_at),
        },
        "meta": {
            "timestamp": datetime.utcnow().isoformat(),
            "version": "v1"
        }
    }


@app.post("/api/v1/auth/logout")
def logout_user():
    """Déconnecter l'utilisateur."""
    return {
        "data": {"message": "Déconnexion réussie"},
        "meta": {
            "timestamp": datetime.utcnow().isoformat(),
            "version": "v1"
        }
    }
# ============================================================
# FIN AUTH ENDPOINTS
# ============================================================

# Include API routers
from app.api.v1 import users
from app.api.v1 import auth
from app.api.v1 import predictions
from app.api.v1 import backtesting
from app.api.v1 import leaderboard
from app.api.v1 import badges
from app.api.public.v1 import predictions as public_predictions
from app.api.public.v1 import matches as public_matches

# #region agent log
write_debug_log("C", "main.py:101", "Including routers", {
    "routers": ["users", "auth", "predictions", "backtesting", "leaderboard", "badges", "public_predictions", "public_matches"]
})
# #endregion

app.include_router(users.router, prefix="/api/v1/users", tags=["users"])
app.include_router(auth.router, prefix="/api/v1/auth", tags=["auth"])
app.include_router(predictions.router)
app.include_router(backtesting.router)
app.include_router(leaderboard.router)
app.include_router(badges.router, prefix="/api/v1/badges", tags=["badges"])

# Public API routers
app.include_router(public_predictions.router)
app.include_router(public_matches.router)

# Trigger reload
