import json

from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy.orm import Session as DbSession

from app.auth import verify_api_key
from app.database import get_db
from app.models import ExternalData, Session, User
from app.schemas import ExternalDataCreate, ExternalDataPublic, SessionPublic, UserPublic

router = APIRouter(prefix="/api/v1", tags=["external-api"])


@router.get("/users/{user_id}", response_model=UserPublic)
def get_user(
    user_id: int,
    _: None = Depends(verify_api_key),
    db: DbSession = Depends(get_db),
):
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    return user


@router.get("/users/by-email/{email}", response_model=UserPublic)
def get_user_by_email(
    email: str,
    _: None = Depends(verify_api_key),
    db: DbSession = Depends(get_db),
):
    user = db.query(User).filter(User.email == email.strip().lower()).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    return user


@router.get("/users/{user_id}/sessions", response_model=list[SessionPublic])
def get_user_sessions(
    user_id: int,
    active_only: bool = True,
    _: None = Depends(verify_api_key),
    db: DbSession = Depends(get_db),
):
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    query = db.query(Session).filter(Session.user_id == user_id)
    if active_only:
        query = query.filter(Session.is_active.is_(True))
    return query.order_by(Session.created_at.desc()).all()


@router.post("/users/{user_id}/data", response_model=ExternalDataPublic, status_code=status.HTTP_201_CREATED)
def write_external_data(
    user_id: int,
    body: ExternalDataCreate,
    _: None = Depends(verify_api_key),
    db: DbSession = Depends(get_db),
):
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")

    payload_str = body.payload if isinstance(body.payload, str) else json.dumps(body.payload, ensure_ascii=False)

    record = ExternalData(user_id=user_id, source=body.source, payload=payload_str)
    db.add(record)

    if body.points_delta:
        user.points = max(0, user.points + body.points_delta)
    if body.rating_delta:
        user.rating = max(0.0, user.rating + body.rating_delta)

    db.commit()
    db.refresh(record)
    return record


@router.get("/users/{user_id}/data", response_model=list[ExternalDataPublic])
def get_external_data(
    user_id: int,
    limit: int = 50,
    _: None = Depends(verify_api_key),
    db: DbSession = Depends(get_db),
):
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
    limit = min(max(limit, 1), 100)
    return (
        db.query(ExternalData)
        .filter(ExternalData.user_id == user_id)
        .order_by(ExternalData.created_at.desc())
        .limit(limit)
        .all()
    )
