# retoor <retoor@molodetz.nl>

import logging
from typing import Annotated

from fastapi import Depends, APIRouter, Request
from fastapi.responses import JSONResponse

from devplacepy.database import get_table, is_account_active
from devplacepy.utils import verify_password_async, get_current_user
from devplacepy.models import LoginForm
from devplacepy.dependencies import json_or_form
from devplacepy.services.access_tokens import issue_token
from devplacepy.services.audit import record as audit

logger = logging.getLogger(__name__)
router = APIRouter()


@router.post("/token")
async def token(
    request: Request,
    data: Annotated[LoginForm, Depends(json_or_form(LoginForm))],
):
    identifier = data.email.strip().lower()
    password = data.password

    if not identifier or not password:
        return JSONResponse(
            {"error": "email and password are required"},
            status_code=400,
        )

    users = get_table("users")
    user = users.find_one(email=identifier) or users.find_one(
        username=identifier
    )

    if not user or not await verify_password_async(
        password, user.get("password_hash", "")
    ):
        audit.record(
            request,
            "auth.token.failure",
            user=None,
            actor_kind="guest",
            result="failure",
            metadata={"identifier": identifier},
            summary=f"failed token request for {identifier}",
        )
        return JSONResponse(
            {"error": "Invalid credentials"},
            status_code=401,
        )

    if not is_account_active(user):
        audit.record(
            request,
            "auth.token.failure",
            user=None,
            actor_kind="guest",
            result="failure",
            metadata={"identifier": identifier, "reason": "inactive"},
            summary=f"token request for inactive user {identifier}",
        )
        return JSONResponse(
            {"error": "Account is deactivated"},
            status_code=403,
        )

    token = issue_token(user)

    logger.info("Token issued for %s", user["username"])
    audit.record(
        request,
        "auth.token.issued",
        user=user,
        target_type="user",
        target_uid=user["uid"],
        target_label=user["username"],
        metadata={"token_uid": token["uid"], "expires_in": token["expires_in"]},
        summary=f"access token issued for {user['username']}",
        links=[audit.target("user", user["uid"], user["username"])],
    )

    return JSONResponse(
        {
            "access_token": token["access_token"],
            "token_type": token["token_type"],
            "expires_in": token["expires_in"],
        }
    )
