from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from starlette.requests import Request

from app.core.security import (
    create_access_token,
    get_access_token_expire_seconds,
    verify_password,
)
from app.core.rbac import get_current_active_user, get_user_permission_names
from app.db.database import get_db
from app.models.user import User
from app.repositories.user_repository import UserRepository
from app.schemas.rbac import CurrentUserResponse
from app.schemas.user import LoginRequest, LoginResponse
from app.services.audit_service import write_audit_log

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


@router.post("/login", response_model=LoginResponse)
def login(
    login: LoginRequest,
    request: Request,
    db: Session = Depends(get_db),
):
    user = UserRepository.get_by_username(db, login.username)

    if not user:
        write_audit_log(
            db,
            action="auth.login.failed",
            entity_type="auth",
            entity_label=login.username,
            actor_username=login.username,
            request=request,
        )
        raise HTTPException(
            status_code=401,
            detail="Ungültige Anmeldedaten",
        )

    if not verify_password(login.password, user.password_hash):
        write_audit_log(
            db,
            action="auth.login.failed",
            entity_type="auth",
            entity_label=login.username,
            actor_user_id=user.id,
            actor_username=user.username,
            request=request,
        )
        raise HTTPException(
            status_code=401,
            detail="Ungültige Anmeldedaten",
        )

    token = create_access_token(user.username)
    write_audit_log(
        db,
        action="auth.login.success",
        entity_type="auth",
        entity_id=user.id,
        entity_label=user.username,
        actor=user,
        request=request,
    )

    return {
        "access_token": token,
        "token_type": "bearer",
        "expires_in": get_access_token_expire_seconds(),
        "user": user,
    }


@router.get("/me", response_model=CurrentUserResponse)
def me(current_user: User = Depends(get_current_active_user)):
    return {
        "id": current_user.id,
        "first_name": current_user.first_name,
        "last_name": current_user.last_name,
        "username": current_user.username,
        "email": current_user.email,
        "role": current_user.primary_role.name,
        "permissions": sorted(get_user_permission_names(current_user)),
    }
