# retoor <retoor@molodetz.nl>

import logging
from datetime import datetime, timezone
from typing import Annotated

from fastapi import APIRouter, Request
from devplacepy.database import get_blocked_uids, get_table
from devplacepy.database.awards import can_give_award, has_giver_cooldown, has_receiver_cooldown
from devplacepy.dependencies import json_or_form
from devplacepy.models import AwardGiveForm
from devplacepy.responses import action_result, json_error, wants_json
from devplacepy.services.audit import record as audit
from devplacepy.services.jobs import queue
from devplacepy.utils import generate_uid, make_combined_slug, require_user

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


@router.post("/{username}/award")
async def give_award(
    request: Request,
    username: str,
    data: Annotated[AwardGiveForm, json_or_form(AwardGiveForm)],
):
    giver = require_user(request)
    target = get_table("users").find_one(username=username)
    redirect = f"/profile/{username}"

    def deny(message: str, status: int = 400):
        if wants_json(request):
            return json_error(status, message)
        return action_result(request, redirect, status_code=302)

    if not target:
        return deny("User not found", 404)
    if target["uid"] == giver["uid"]:
        return deny("You cannot give yourself an award")
    blocked = get_blocked_uids(giver["uid"])
    if target["uid"] in blocked:
        return deny("You cannot give an award to a blocked user")
    reverse_blocked = get_blocked_uids(target["uid"])
    if giver["uid"] in reverse_blocked:
        return deny("You cannot give an award to this user")
    if has_giver_cooldown(giver["uid"]):
        return deny("You can give another award later")
    if has_receiver_cooldown(target["uid"]):
        return deny("This user received an award recently")
    if not (giver.get("api_key") or "").strip():
        return deny("Your account has no API key for award generation")

    description = data.description.strip()
    uid = generate_uid()
    slug = make_combined_slug(description, uid)
    now = datetime.now(timezone.utc).isoformat()
    get_table("awards").insert(
        {
            "uid": uid,
            "slug": slug,
            "description": description,
            "giver_uid": giver["uid"],
            "receiver_uid": target["uid"],
            "attachment_uid_512": "",
            "attachment_uid_256": "",
            "attachment_uid_64": "",
            "generated_at": None,
            "created_at": now,
            "job_uid": "",
            "deleted_at": None,
            "deleted_by": None,
        }
    )
    job_uid = queue.enqueue(
        "award",
        {
            "award_uid": uid,
            "giver_uid": giver["uid"],
            "receiver_uid": target["uid"],
            "description": description,
            "api_key": giver.get("api_key", ""),
        },
        "user",
        giver["uid"],
    )
    get_table("awards").update({"uid": uid, "job_uid": job_uid}, ["uid"])
    logger.info("%s gave award %s to %s", giver["username"], uid, username)
    audit.record(
        request,
        "award.give",
        user=giver,
        target_type="user",
        target_uid=target["uid"],
        target_label=username,
        summary=f"{giver['username']} gave award to {username}",
        links=[
            audit.target("user", target["uid"], username),
            audit.target("award", uid, slug),
            audit.job(job_uid),
        ],
    )
    return action_result(
        request,
        redirect,
        data={"ok": True, "award_uid": uid, "award_slug": slug},
    )