from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, Response
from fastapi import HTTPException

from core.auth.models import CurrentUser
from v1.auth.rate_limit import enforce_rate_limit
from v1.auth.dependencies import get_auth_service
from v1.profile.dependencies import get_current_user
from v1.auth.schemas import (
    AuthResendCodeResponse,
    AuthSignupStartResponse,
    AuthTokenResponse,
    AuthUserByEmailResponse,
    LoginRequest,
    LogoutRequest,
    RefreshRequest,
    SignupResendRequest,
    SignupStartRequest,
    SignupVerifyRequest,
)
from v1.auth.service import AuthService


router = APIRouter(prefix="/auth", tags=["auth"])


@router.post("/signup/start", response_model=AuthSignupStartResponse, status_code=202)
async def signup_start(
    payload: SignupStartRequest,
    service: AuthService = Depends(get_auth_service),
) -> AuthSignupStartResponse:
    await enforce_rate_limit(
        scope="signup_start",
        identifier=payload.email,
        limit=5,
        window_seconds=60,
    )
    return await service.signup_start(payload)


@router.post("/signup/verify", response_model=AuthTokenResponse)
async def signup_verify(
    payload: SignupVerifyRequest,
    service: AuthService = Depends(get_auth_service),
) -> AuthTokenResponse:
    await enforce_rate_limit(
        scope="signup_verify",
        identifier=payload.email,
        limit=10,
        window_seconds=600,
    )
    return await service.signup_verify(payload)


@router.post("/signup/resend", response_model=AuthResendCodeResponse)
async def signup_resend(
    payload: SignupResendRequest,
    service: AuthService = Depends(get_auth_service),
) -> AuthResendCodeResponse:
    await enforce_rate_limit(
        scope="signup_resend",
        identifier=payload.email,
        limit=3,
        window_seconds=60,
    )
    return await service.signup_resend(payload)


@router.post("/login", response_model=AuthTokenResponse)
async def login(
    payload: LoginRequest,
    service: AuthService = Depends(get_auth_service),
) -> AuthTokenResponse:
    return await service.login(payload)


@router.post("/refresh", response_model=AuthTokenResponse)
async def refresh(
    payload: RefreshRequest,
    service: AuthService = Depends(get_auth_service),
) -> AuthTokenResponse:
    return await service.refresh(payload)


@router.post("/logout", status_code=204)
async def logout(
    payload: LogoutRequest,
    service: AuthService = Depends(get_auth_service),
) -> Response:
    await service.logout(payload.refresh_token)
    return Response(status_code=204)


@router.get("/users/by-email", response_model=AuthUserByEmailResponse)
async def get_user_by_email(
    email: str,
    current_user: Annotated[CurrentUser, Depends(get_current_user)],
    service: AuthService = Depends(get_auth_service),
) -> AuthUserByEmailResponse:
    if current_user.role != "service_role" and current_user.email != email:
        raise HTTPException(status_code=403, detail="Forbidden")
    return await service.get_user_by_email(email)
