from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from backend.app.core.config import settings from backend.app.core.database import get_session from backend.app.core.security import ( create_access_token, verify_telegram_login, verify_telegram_webapp, ) from backend.app.models.rider import Rider from backend.app.schemas.auth import ( AuthResponse, TelegramLoginRequest, TelegramWebAppRequest, ) router = APIRouter() async def _upsert_rider( session: AsyncSession, telegram_id: int, first_name: str, last_name: str | None, username: str | None, photo_url: str | None, ) -> Rider: result = await session.execute( select(Rider).where(Rider.telegram_id == telegram_id) ) rider = result.scalar_one_or_none() name = first_name if last_name: name = f"{first_name} {last_name}" if not rider: rider = Rider( telegram_id=telegram_id, name=name, telegram_username=username, avatar_url=photo_url, ) session.add(rider) else: rider.name = name rider.telegram_username = username rider.avatar_url = photo_url await session.commit() await session.refresh(rider) return rider def _build_auth_response(rider: Rider) -> AuthResponse: token = create_access_token( rider_id=str(rider.id), telegram_id=rider.telegram_id, secret=settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM, expires_minutes=settings.JWT_ACCESS_TOKEN_EXPIRE_MINUTES, ) return AuthResponse(access_token=token, rider=rider) @router.post("/telegram-login", response_model=AuthResponse) async def telegram_login( data: TelegramLoginRequest, session: AsyncSession = Depends(get_session), ): if not settings.TELEGRAM_BOT_TOKEN: raise HTTPException(status_code=500, detail="Telegram bot token not configured") login_data = data.model_dump() if not verify_telegram_login(login_data, settings.TELEGRAM_BOT_TOKEN): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid Telegram authorization", ) rider = await _upsert_rider( session, telegram_id=data.id, first_name=data.first_name, last_name=data.last_name, username=data.username, photo_url=data.photo_url, ) return _build_auth_response(rider) @router.post("/telegram-webapp", response_model=AuthResponse) async def telegram_webapp( data: TelegramWebAppRequest, session: AsyncSession = Depends(get_session), ): if not settings.TELEGRAM_BOT_TOKEN: raise HTTPException(status_code=500, detail="Telegram bot token not configured") user = verify_telegram_webapp(data.init_data, settings.TELEGRAM_BOT_TOKEN) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid Telegram WebApp data", ) rider = await _upsert_rider( session, telegram_id=user["id"], first_name=user.get("first_name", ""), last_name=user.get("last_name"), username=user.get("username"), photo_url=user.get("photo_url"), ) return _build_auth_response(rider)