import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { capturePayment, executePayout } from "@/lib/payment";
import { TaskStatus } from "@agent-bounty/contracts";
import crypto from "crypto";

function isValidGithubSignature(rawBody: string, signature: string | null) {
  const secret = process.env.GITHUB_WEBHOOK_SECRET;
  if (!secret || !signature?.startsWith("sha256=")) {
    return false;
  }

  const expected = `sha256=${crypto.createHmac("sha256", secret).update(rawBody).digest("hex")}`;
  const actualBuffer = Buffer.from(signature);
  const expectedBuffer = Buffer.from(expected);
  return actualBuffer.length === expectedBuffer.length &&
    crypto.timingSafeEqual(actualBuffer, expectedBuffer);
}

export async function POST(request: NextRequest) {
  try {
    const rawBody = await request.text();
    if (!isValidGithubSignature(rawBody, request.headers.get("x-hub-signature-256"))) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const eventType = request.headers.get("x-github-event");
    
    // We only care about pull request events
    if (eventType !== "pull_request") {
      return NextResponse.json({ received: true });
    }

    const payload = JSON.parse(rawBody);

    // When a PR is merged, the action is "closed" and "merged" is true.
    if (payload.action === "closed" && payload.pull_request) {
      const pr = payload.pull_request;
      if (pr.merged) {
        const prUrl = pr.html_url;

        // Find the Task associated with this PR
        const task = await prisma.task.findFirst({
          where: {
            github_pr_url: prUrl,
            status: TaskStatus.PENDING_REVIEW,
          },
        });

        if (task) {
          // Arbitrary point conversion: 1 USD cent = 1 Point
          const points = task.reward_amount;

          await prisma.$transaction(async (tx) => {
            // Update Task to COMPLETED
            await tx.task.update({
              where: { id: task.id },
              data: {
                status: TaskStatus.COMPLETED,
                reward_points: points,
              },
            });

            // Find the active claim for this task
            const claim = await tx.claim.findFirst({
              where: { task_id: task.id, status: TaskStatus.PENDING_REVIEW },
              orderBy: { created_at: "desc" }
            });

            if (claim) {
              await tx.claim.update({
                where: { id: claim.id },
                data: { status: TaskStatus.COMPLETED },
              });
              
              // Process payout
              await capturePayment(tx, task.id, `${claim.id}-capture-pr`);
              await executePayout(tx, task.id, claim.developer_wallet, claim.held_amount, claim.held_currency, `${claim.id}-payout-pr`);
            }
          });

          console.log(`[GitHub Webhook] PR merged. Task ${task.id} COMPLETED and paid.`);
        } else {
          console.log(`[GitHub Webhook] No PENDING_REVIEW task found for PR: ${prUrl}`);
        }
      }
    }

    return NextResponse.json({ received: true });
  } catch (error: unknown) {
    console.error("[GitHub Webhook Error]", error);
    return NextResponse.json({ error: "Internal Error" }, { status: 500 });
  }
}
