# retoor <retoor@molodetz.nl>
import logging
from typing import Annotated
from datetime import datetime, timezone
from fastapi import Depends, APIRouter, Request
from fastapi.responses import RedirectResponse, JSONResponse
from devplacepy.database import get_table, db, _now_iso
from devplacepy.utils import generate_uid, require_user, track_action, redirect_back
from devplacepy.models import ReactionForm
from devplacepy.services.audit import record as audit
from devplacepy.dependencies import json_or_form

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

REACTABLE: set[str] = {"post", "comment", "gist", "project", "quiz"}

@router.post("/{target_type}/{target_uid}")
async def react(
    request: Request,
    target_type: str,
    target_uid: str,
    data: Annotated[ReactionForm, Depends(json_or_form(ReactionForm))],
):
    user = require_user(request)
    if target_type not in REACTABLE:
        return JSONResponse({"error": "Invalid target"}, status_code=400)

    emoji = data.emoji
    reactions = get_table("reactions")
    existing = reactions.find_one(
        user_uid=user["uid"],
        target_uid=target_uid,
        target_type=target_type,
        emoji=emoji,
    )
    if existing and existing.get("deleted_at"):
        reactions.update(
            {"id": existing["id"], "deleted_at": None, "deleted_by": None}, ["id"]
        )
        added = True
    elif existing:
        reactions.update(
            {"id": existing["id"], "deleted_at": _now_iso(), "deleted_by": user["uid"]},
            ["id"],
        )
        added = False
    else:
        reactions.insert(
            {
                "uid": generate_uid(),
                "user_uid": user["uid"],
                "target_uid": target_uid,
                "target_type": target_type,
                "emoji": emoji,
                "created_at": datetime.now(timezone.utc).isoformat(),
                "deleted_at": None,
                "deleted_by": None,
            }
        )
        added = True

    reaction_event = "reaction.add" if added else "reaction.remove"
    if added:
        track_action(user["uid"], "reaction")

    audit.record(
        request,
        reaction_event,
        user=user,
        target_type=target_type,
        target_uid=target_uid,
        metadata={"emoji": emoji},
        summary=f"{user['username']} {'added' if added else 'removed'} {emoji} on {target_type} {target_uid}",
        links=[audit.target(target_type, target_uid)],
    )

    counts = {
        row["emoji"]: row["c"]
        for row in db.query(
            "SELECT emoji, COUNT(*) as c FROM reactions WHERE target_type=:tt AND target_uid=:tu AND deleted_at IS NULL GROUP BY emoji",
            tt=target_type,
            tu=target_uid,
        )
    }
    mine = [
        row["emoji"]
        for row in reactions.find(
            user_uid=user["uid"],
            target_uid=target_uid,
            target_type=target_type,
            deleted_at=None,
        )
    ]

    if request.headers.get("x-requested-with") == "fetch":
        return JSONResponse({"counts": counts, "mine": mine})
    return RedirectResponse(url=redirect_back(request), status_code=302)
