import logging
from datetime import datetime, timezone
from fastapi import APIRouter, Request
from fastapi.responses import RedirectResponse
from devplacepy.database import get_table
from devplacepy.templating import clear_unread_cache
from devplacepy.utils import generate_uid, require_user

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


@router.post("/{target_type}/{target_uid}")
async def vote(request: Request, target_type: str, target_uid: str):
    user = require_user(request)
    form = await request.form()
    value = int(form.get("value", "1"))

    if value not in (1, -1):
        return RedirectResponse(url="/feed", status_code=302)

    votes = get_table("votes")
    existing = votes.find_one(user_uid=user["uid"], target_uid=target_uid, target_type=target_type)

    if existing:
        if int(existing["value"]) == value:
            votes.delete(id=existing["id"])
        else:
            votes.update({"id": existing["id"], "value": value}, ["id"])
    else:
        votes.insert({
            "uid": generate_uid(),
            "user_uid": user["uid"],
            "target_uid": target_uid,
            "target_type": target_type,
            "value": value,
            "created_at": datetime.now(timezone.utc).isoformat(),
        })

    up_count = len(list(votes.find(target_uid=target_uid, value=1)))
    down_count = len(list(votes.find(target_uid=target_uid, value=-1)))
    net = up_count - down_count

    if target_type == "post":
        posts = get_table("posts")
        posts.update({"uid": target_uid, "stars": net}, ["uid"])
    elif target_type == "project":
        projects = get_table("projects")
        projects.update({"uid": target_uid, "stars": net}, ["uid"])
    elif target_type == "gist":
        gists = get_table("gists")
        gists.update({"uid": target_uid, "stars": net}, ["uid"])

    if value == 1:
        target_owner_uid = None
        if target_type == "post":
            target_owner = posts.find_one(uid=target_uid)
            if target_owner:
                target_owner_uid = target_owner["user_uid"]
        elif target_type == "comment":
            comments = get_table("comments")
            target_comment = comments.find_one(uid=target_uid)
            if target_comment:
                target_owner_uid = target_comment["user_uid"]
        elif target_type == "gist":
            gists = get_table("gists")
            target_gist = gists.find_one(uid=target_uid)
            if target_gist:
                target_owner_uid = target_gist["user_uid"]

        if target_owner_uid and target_owner_uid != user["uid"]:
            label = {"post": "post", "comment": "comment", "gist": "gist"}.get(target_type, "gist")
            notifications = get_table("notifications")
            notifications.insert({
                "uid": generate_uid(),
                "user_uid": target_owner_uid,
                "type": "vote",
                "message": f"{user['username']} ++'d your {label}",
                "related_uid": user["uid"],
                "read": False,
                "created_at": datetime.now(timezone.utc).isoformat(),
            })
            clear_unread_cache(target_owner_uid)

    referer = request.headers.get("Referer", "/feed")
    return RedirectResponse(url=referer, status_code=302)
