/**
 * POST /api/comments/[id]/vote   { vote: 1 | -1 | 0 }
 *
 * Up/down/clear vote on an article comment. Uses the existing
 * polymorphic forum_votes table (target_type='comment').
 *
 * 0 → remove your existing vote (toggle).
 */
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";

export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const { id } = await ctx.params;
  const sb = await createClient();
  const { data: { user } } = await sb.auth.getUser();
  if (!user) return NextResponse.json({ error: "Sign in to vote" }, { status: 401 });

  let body: { vote?: number };
  try { body = await req.json(); }
  catch { return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); }

  const v = body.vote === 1 ? 1 : body.vote === -1 ? -1 : 0;

  // Always look up the current vote first so we can compute the diff
  // and apply it atomically to the comment's denormalized counters.
  const { data: existing } = await sb
    .from("forum_votes")
    .select("id, vote_value")
    .eq("user_id", user.id)
    .eq("target_type", "comment")
    .eq("target_id", id)
    .maybeSingle();

  let upDelta = 0, downDelta = 0;
  if (existing) {
    // Reverse the existing vote's counter contribution first
    if (existing.vote_value === 1) upDelta -= 1;
    else if (existing.vote_value === -1) downDelta -= 1;

    if (v === 0) {
      await sb.from("forum_votes").delete().eq("id", existing.id);
    } else {
      await sb.from("forum_votes")
        .update({ vote_value: v, updated_at: new Date().toISOString() })
        .eq("id", existing.id);
      if (v === 1) upDelta += 1; else downDelta += 1;
    }
  } else if (v !== 0) {
    await sb.from("forum_votes").insert({
      user_id: user.id, target_type: "comment", target_id: id, vote_value: v,
    });
    if (v === 1) upDelta += 1; else downDelta += 1;
  }

  // Apply counter delta to the comment row. Use rpc/raw fragment to add
  // integers atomically (supabase-js doesn't expose increment; we read &
  // write — racy under heavy concurrency but acceptable for forum scale).
  const { data: cur } = await sb
    .from("article_comments")
    .select("upvotes, downvotes")
    .eq("id", id)
    .maybeSingle();
  if (cur) {
    const upvotes = Math.max(0, (cur.upvotes || 0) + upDelta);
    const downvotes = Math.max(0, (cur.downvotes || 0) + downDelta);
    await sb.from("article_comments").update({
      upvotes, downvotes, vote_score: upvotes - downvotes,
    }).eq("id", id);
  }

  return NextResponse.json({ ok: true, vote: v });
}
