"""
Auth service routes for Memos-style backend.

Router chỉ chứa định nghĩa API, logic xác thực nằm ở memos_core.services.auth.
"""

# ruff: noqa: I001
from fastapi import APIRouter, Body, Depends, HTTPException, Header

from common.memos_core.schemas import (
    AuthSignInRequest,
    AuthSignInResponse,
    AuthSignUpRequest,
    AuthSignUpResponse,
)
from common.memos_core.services import get_auth_service
from config import DISABLE_AUTH


router = APIRouter(prefix="/auth")


@router.post("/signin", summary="Sign in", response_model=AuthSignInResponse)
async def signin(
    payload: dict = Body(default_factory=dict),  # noqa: B008
    auth_service=Depends(get_auth_service),  # noqa: B008 (FastAPI dependency)
):
    try:
        # Accept both REST payload and Connect/proto-like envelope.
        # REST: { "email": "...", "password": "..." }
        # Connect/proto-like: { "credentials": { "case": "passwordCredentials", "value": { "username": "...", "password": "..." } } }
        raw = payload if isinstance(payload, dict) else {}

        # Normalize Connect-style password credentials into legacy fields.
        creds = raw.get("credentials") if isinstance(raw, dict) else None
        if isinstance(creds, dict):
            case = creds.get("case")
            value = creds.get("value")
            if case == "passwordCredentials" and isinstance(value, dict):
                raw = {
                    "email": value.get("username"),
                    "password": value.get("password"),
                    **raw,
                }

        signin_req = AuthSignInRequest(**(raw or {}))
        result = await auth_service.sign_in(signin_req)
        # Ensure camelCase keys for Connect/proto TS client.
        return result.model_dump(by_alias=True)
    except Exception as exc:  # pragma: no cover - placeholder
        raise HTTPException(status_code=400, detail=str(exc)) from exc


@router.post("/signup", summary="Sign up", response_model=AuthSignUpResponse)
async def signup(
    payload: AuthSignUpRequest,
    auth_service=Depends(get_auth_service),  # noqa: B008 (FastAPI dependency)
):
    try:
        return await auth_service.sign_up(payload)
    except Exception as exc:  # pragma: no cover - placeholder
        raise HTTPException(status_code=400, detail=str(exc)) from exc


@router.get("/me", summary="Get current user")
@router.post("/me", summary="Get current user (Connect compatibility)")
async def get_me(
    authorization: str | None = Header(default=None),
    auth_service=Depends(get_auth_service),  # noqa: B008 (FastAPI dependency)
):
    try:
        token = None
        if authorization and authorization.startswith("Bearer "):
            token = authorization.split(" ", 1)[1]
        
        me = await auth_service.get_me(token=token)
        
        # Build username - prefer me.username, fallback to email prefix
        username = getattr(me, "username", None) or (
            me.email.split("@", 1)[0] if getattr(me, "email", None) else "user"
        )
        
        # Build display name from firstName + lastName
        first_name = getattr(me, "first_name", None) or ""
        last_name = getattr(me, "last_name", None) or ""
        display_name = f"{first_name} {last_name}".strip() or username
        
        avatar_url = getattr(me, "avatar_url", None) or ""
        
        # Connect/proto expects: { "user": User }
        # CRITICAL: Use me.id (Clerk user ID) for proper user data isolation!
        return {
            "user": {
                "name": f"users/{me.id}",
                "role": 1,  # HOST
                "username": username,
                "email": getattr(me, "email", ""),
                "displayName": display_name,
                "avatarUrl": avatar_url,
                "description": "",
                "password": "",
                "state": 1,
            }
        }
    except Exception as exc:  # pragma: no cover - placeholder
        # In local/dev mode, don't break the app just because auth fails.
        # Fall back to a demo user so that memo features still work.
        if DISABLE_AUTH:
            return {
                "user": {
                    "name": "users/1",
                    "role": 1,  # HOST
                    "username": "demo",
                    "email": "demo@example.com",
                    "displayName": "",
                    "avatarUrl": "",
                    "description": "",
                    "password": "",
                    "state": 1,
                }
            }

        raise HTTPException(status_code=401, detail=str(exc)) from exc


