# retoor <retoor@molodetz.nl>

import logging
from typing import Annotated

from fastapi import Depends, APIRouter, Request

from devplacepy.attachments import (
    get_orphan_attachments_batch,
    link_attachments,
    schedule_gitea_mirror,
    split_attachment_uids,
)
from devplacepy.database import get_table
from devplacepy.models import IssueCommentForm
from devplacepy.responses import action_result, json_error
from devplacepy.services.audit import record as audit
from devplacepy.services.gitea import runtime, store
from devplacepy.services.gitea.client import GiteaError
from devplacepy.services.gitea.config import gitea_config
from devplacepy.services.background import background
from devplacepy.utils import create_notification, require_user
from devplacepy.dependencies import json_or_form

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


def _notify_admins(actor: dict, number: int) -> None:
    for admin in get_table("users").find(role="Admin"):
        if admin["uid"] == actor["uid"]:
            continue
        create_notification(
            admin["uid"],
            "issue",
            f"{actor['username']} commented on issue #{number}",
            str(number),
            f"/issues/{number}",
        )

@router.post("/{number}/comment")
async def comment_issue(
    request: Request, number: int, data: Annotated[IssueCommentForm, Depends(json_or_form(IssueCommentForm))]
):
    user = require_user(request)
    if not gitea_config().is_configured:
        return json_error(503, "The issue tracker is not configured")
    client = runtime.get_client()
    body = (
        f"{data.body.strip()}\n\n---\n"
        f"*Posted by **{user['username']}** via DevPlace.*"
    )
    try:
        comment = await client.create_comment(number, body)
    except GiteaError as exc:
        logger.warning("Could not post comment on #%s: %s", number, exc)
        audit.record(
            request,
            "issue.comment",
            user=user,
            result="failure",
            target_type="issue",
            target_uid=str(number),
            summary=f"Failed to comment on issue #{number}: {exc}",
        )
        return json_error(exc.status or 502, "Could not post the comment")

    comment_id = int(comment.get("id", 0))
    store.record_comment_author(comment_id, number, user["uid"])
    owned = get_orphan_attachments_batch(
        split_attachment_uids(data.attachment_uids), user
    )
    if owned:
        link_attachments(owned, "issue_comment", str(comment_id))
        for uid in owned:
            schedule_gitea_mirror(uid)
    background.submit(_notify_admins, user, number)
    audit.record(
        request,
        "issue.comment",
        user=user,
        target_type="issue",
        target_uid=str(number),
        summary=f"{user['username']} commented on issue #{number}",
        metadata={"number": number, "comment_id": comment_id},
        links=[audit.target("issue", str(number))],
    )
    logger.info("Comment posted on issue #%s by %s", number, user["username"])
    return action_result(request, f"/issues/{number}", data={"comment_id": comment_id})
