from typing import Annotated

from fastapi import APIRouter, Depends, Request, Security
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy.ext.asyncio import AsyncSession

from app.auth.repository import AuthRepository
from app.auth.schemas import (
    LoginRequest,
    LoginResponse,
    LogoutRequest,
    LogoutResponse,
    UserProfile,
)
from app.auth.service import AuthService
from app.config import Settings, get_settings
from app.db import get_session
from app.security import (
    CurrentPrincipal,
    decode_jwt_token,
)

router = APIRouter(tags=["auth"])
optional_bearer = HTTPBearer(auto_error=False)


def get_auth_service(
    session: Annotated[AsyncSession, Depends(get_session)],
    settings: Annotated[Settings, Depends(get_settings)],
) -> AuthService:
    return AuthService(AuthRepository(session), settings)


AuthServiceDependency = Annotated[AuthService, Depends(get_auth_service)]


@router.post(
    "/api/auth/login",
    response_model=LoginResponse,
    summary="Login pengguna atau sales",
)
@router.post(
    "/api/login",
    response_model=LoginResponse,
    include_in_schema=False,
)
async def login(
    request: Request,
    body: LoginRequest,
    service: AuthServiceDependency,
) -> LoginResponse:
    client_ip = request.client.host if request.client else None
    return await service.authenticate(body, client_ip=client_ip)


@router.get(
    "/api/auth/me",
    response_model=UserProfile,
    summary="Lihat profil pengguna yang sedang login",
)
@router.get(
    "/api/me",
    response_model=UserProfile,
    include_in_schema=False,
)
async def get_me(
    principal: CurrentPrincipal,
    credentials: Annotated[
        HTTPAuthorizationCredentials | None, Security(optional_bearer)
    ],
    settings: Annotated[Settings, Depends(get_settings)],
) -> UserProfile:
    token_payload = {}
    if credentials and credentials.scheme.lower() == "bearer":
        token_payload = decode_jwt_token(credentials.credentials, settings) or {}

    return UserProfile(
        user_code=principal.user_code,
        user_name=principal.user_name,
        role=principal.role,
        hak_akses=token_payload.get("hak_akses") or principal.role,
        kode_divisi=token_payload.get("kode_divisi"),
        source=token_payload.get("source")
        or ("SALES" if principal.role == "SALES" else "PENGGUNA"),
        kode_sales=principal.kode_sales,
    )


@router.post(
    "/api/auth/logout",
    response_model=LogoutResponse,
    summary="Logout dan catat waktu logout",
)
@router.post(
    "/api/logout",
    response_model=LogoutResponse,
    include_in_schema=False,
)
async def logout(
    principal: CurrentPrincipal,
    service: AuthServiceDependency,
    body: LogoutRequest | None = None,
    credentials: Annotated[
        HTTPAuthorizationCredentials | None, Security(optional_bearer)
    ] = None,
    settings: Annotated[Settings, Depends(get_settings)] = None,  # type: ignore[assignment]
) -> LogoutResponse:
    login_id = body.login_id if body and body.login_id else None
    if (
        login_id is None
        and credentials
        and credentials.scheme.lower() == "bearer"
        and settings
    ):
        payload = decode_jwt_token(credentials.credentials, settings) or {}
        login_id = payload.get("login_id")
    return await service.logout(principal.user_code, login_id)
