from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from app.api.deps import CurrentUserContext, get_current_user, get_db
from app.schemas.auth import (
    AuthUserRead,
    LoginRequest,
    LoginResponse,
    LogoutRequest,
    LogoutResponse,
    SessionFinishRequest,
    SessionFinishResponse,
)
from app.schemas.common import ErrorResponse
from app.services.auth import AuthService
from app.services.auth_sessions import AuthSessionService
from app.services.user_session_metrics import UserSessionMetricService

router = APIRouter(prefix="/auth")
DbSession = Annotated[Session, Depends(get_db)]


@router.post(
    "/login",
    response_model=LoginResponse,
    summary="用户登录",
    description="支持管理员账号和员工账号登录，成功后返回前端会话所需的用户信息。",
    responses={
        status.HTTP_401_UNAUTHORIZED: {
            "model": ErrorResponse,
            "description": "账号或密码错误。",
        }
    },
)
def login(payload: LoginRequest, db: DbSession) -> LoginResponse:
    try:
        return AuthService(db).login(payload)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(exc)) from exc


@router.get(
    "/me",
    response_model=AuthUserRead,
    summary="读取当前登录用户",
    description="根据 Bearer 会话刷新前端登录态中的员工姓名、部门、岗位和职级。",
)
def get_current_auth_user(
    current_user: Annotated[CurrentUserContext, Depends(get_current_user)],
    db: DbSession,
) -> AuthUserRead:
    user = AuthService(db).get_user_snapshot(
        current_user.username,
        tenant_id=current_user.tenant_id,
    )
    if user is not None:
        return user

    if current_user.is_admin:
        name = current_user.name or current_user.username or "系统管理员"
        return AuthUserRead(
            username=current_user.username or name,
            name=name,
            role="管理员",
            department=current_user.department_name,
            departmentName=current_user.department_name,
            position=current_user.position or "系统管理员",
            grade=current_user.grade,
            employeeNo=current_user.employee_no,
            managerName=current_user.manager_name,
            costCenter=current_user.cost_center,
            roleCodes=current_user.role_codes or ["manager"],
            email=(
                current_user.username
                if "@" in current_user.username
                else f"{current_user.username}@local"
            ),
            avatar=name[:1].upper(),
            isAdmin=True,
            tenantId=current_user.tenant_id,
        )

    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="当前登录用户不存在或已停用",
    )


@router.post(
    "/logout",
    response_model=LogoutResponse,
    summary="退出当前登录会话",
    description="撤销当前 Bearer Token；撤销后该凭证不可再次使用。",
)
def logout(
    payload: LogoutRequest,
    current_user: Annotated[CurrentUserContext, Depends(get_current_user)],
    db: DbSession,
) -> LogoutResponse:
    try:
        if payload.sessionId:
            UserSessionMetricService(db).finish_session(
                session_id=payload.sessionId,
                expected_username=current_user.username,
                reason=payload.reason,
                last_activity_at=payload.lastActivityAt,
                activity_event_count=payload.activityEventCount,
                event={"page_path": payload.pagePath},
                commit=False,
            )
        AuthSessionService(db).revoke(current_user.auth_session_id, commit=False)
        db.commit()
    except Exception:
        db.rollback()
        raise
    return LogoutResponse()


@router.post(
    "/sessions/{session_id}/finish",
    response_model=SessionFinishResponse,
    summary="结算用户在线会话",
)
def finish_session(
    session_id: str,
    payload: SessionFinishRequest,
    current_user: Annotated[CurrentUserContext, Depends(get_current_user)],
    db: DbSession,
) -> SessionFinishResponse:
    session = UserSessionMetricService(db).finish_session(
        session_id=session_id,
        expected_username=current_user.username,
        reason=payload.reason,
        last_activity_at=payload.lastActivityAt,
        activity_event_count=payload.activityEventCount,
        event={"page_path": payload.pagePath},
    )
    if session is None:
        return SessionFinishResponse(
            detail="会话不存在或已被清理。",
            sessionId=session_id,
            durationMs=0,
        )
    return SessionFinishResponse(
        sessionId=session.session_id,
        durationMs=int(session.duration_ms or 0),
    )
