import uuid from fastapi import APIRouter, Depends from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from ...auth import verify_token from ...config import settings from ...domain.services.account_service import AccountService from ...languages import SUPPORTED_LANGUAGES, SUPPORTED_LEVELS, LEVEL_ORDER, LEVEL_DESCRIPTIONS from ...outbound.postgres.database import get_db from ...outbound.postgres.repositories import email_verification_token_repository router = APIRouter(prefix="/account", tags=["bff"]) class LanguagePairOption(BaseModel): value: str label: str description: str class ProficiencyOption(BaseModel): value: str label: str description: str class OnboardingResponse(BaseModel): _todo_remove_me_validate_account_link: str | None = None language_pairs: list[LanguagePairOption] proficiencies: list[ProficiencyOption] model_config = {"populate_by_name": True} def _build_language_pairs() -> list[LanguagePairOption]: pairs = [] for source_code, source_name in SUPPORTED_LANGUAGES.items(): for target_code, target_name in SUPPORTED_LANGUAGES.items(): if source_code == target_code: continue pairs.append( LanguagePairOption( value=f"{source_code},{target_code}", label=f"{source_name} to {target_name}", description=f"You are a {source_name} speaker, learning {target_name}", ) ) return pairs def _build_proficiencies() -> list[ProficiencyOption]: return [ ProficiencyOption( value=level, label=level, description=LEVEL_DESCRIPTIONS[level], ) for level in LEVEL_ORDER if level in SUPPORTED_LEVELS ] class AccountLanguagePair(BaseModel): id: str source_language: str target_language: str proficiencies: list[str] class AccountResponse(BaseModel): email: str human_name: str | None language_pairs: list[AccountLanguagePair] @router.get("", response_model=AccountResponse) async def get_account( db: AsyncSession = Depends(get_db), token_data: dict = Depends(verify_token), ) -> AccountResponse: user_id = uuid.UUID(token_data["sub"]) account = await AccountService(db).get_account(user_id) return AccountResponse( email=account.email, human_name=account.human_name, language_pairs=[ AccountLanguagePair( id=lang.id, source_language=lang.source_language, target_language=lang.target_language, proficiencies=lang.proficiencies, ) for lang in account.learnable_languages ], ) @router.get("/onboarding", response_model=OnboardingResponse) async def get_onboarding( db: AsyncSession = Depends(get_db), token_data: dict = Depends(verify_token), ) -> OnboardingResponse: user_id = uuid.UUID(token_data["sub"]) active_token = await email_verification_token_repository.get_active_for_user(db, user_id) link = ( f"{settings.api_base_url}/api/auth/verify-email?token={active_token.token}" if active_token else None ) return OnboardingResponse( **{"_todo_remove_me_validate_account_link": link}, language_pairs=_build_language_pairs(), proficiencies=_build_proficiencies(), )