from fastapi import APIRouter, HTTPException, status, Depends, Request, Query
from pydantic import BaseModel, EmailStr
from app.auth import get_user_manager, AuthenticationBackendWithRefresh, bearer_transport, get_jwt_strategy, get_refresh_jwt_strategy
from fastapi.responses import JSONResponse

router = APIRouter()

class MagicLinkRequest(BaseModel):
    email: EmailStr

# Path: POST /api/v1/auth/magic-link
@router.post('/magic-link', status_code=status.HTTP_200_OK)
async def send_magic_link(payload: MagicLinkRequest, request: Request, user_manager=Depends(get_user_manager)):
    """Generate a one-time magic-link token and *log* it for now.

    In production this should email the user. For Phase-4 backend milestone we
    simply issue the verification token and return it in the response so the
    frontend can test the flow without an email provider.
    """
    # Ensure user exists (create guest if not)
    user = await user_manager.get_by_email(payload.email)
    if user is None:
        # Auto-register guest account (inactive until verified)
        user_in = {
            'email': payload.email,
            'password': '',  # FastAPI Users requires but we will bypass login
        }
        # Using UserCreate model generically – relies on fastapi-users internals
        try:
            user = await user_manager.create(user_in, safe=True, request=request)
        except Exception:
            raise HTTPException(status_code=400, detail='Unable to create account')

    verification_token = await user_manager.generate_verification_token(user)

    # TODO: send email instead of returning token
    return {'detail': 'Magic link generated (token returned for dev)', 'token': verification_token}


@router.get('/magic-link/verify')
async def verify_magic_link(token: str = Query(...), request: Request = None, user_manager=Depends(get_user_manager)):
    """Verify incoming token and issue standard JWT + refresh tokens."""
    try:
        user = await user_manager.verify(token, request)
    except Exception:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Invalid or expired token')

    # Issue JWT + refresh using existing backend routines
    access_strategy = get_jwt_strategy()
    refresh_strategy = get_refresh_jwt_strategy()
    access_token = await access_strategy.write_token(user)
    refresh_token = await refresh_strategy.write_token(user)

    return JSONResponse(
        {
            'access_token': access_token,
            'refresh_token': refresh_token,
            'token_type': 'bearer',
        }
    ) 