import type { Request, Response } from "express";
import { fulfillPaystackOrder, getOrder } from "./db";
import { isSuccessfulPaystackPayment, verifyPaystackWebhookSignature } from "./paystack";

function readOrderId(metadata: unknown) {
  if (!metadata || typeof metadata !== "object") return null;
  const value = (metadata as { orderId?: unknown }).orderId;
  const orderId = typeof value === "string" ? Number(value) : value;
  return typeof orderId === "number" && Number.isInteger(orderId) && orderId > 0 ? orderId : null;
}

export async function handlePaystackWebhook(req: Request, res: Response) {
  const rawBody = Buffer.isBuffer(req.body) ? req.body : Buffer.from(JSON.stringify(req.body ?? {}));
  if (!verifyPaystackWebhookSignature(rawBody, req.header("x-paystack-signature"))) {
    res.status(401).json({ message: "Invalid Paystack signature" });
    return;
  }
  const payload = JSON.parse(rawBody.toString("utf8")) as { event?: string; data?: { reference?: string; status?: string; amount?: number; currency?: string; metadata?: unknown } };
  if (payload.event !== "charge.success" || !payload.data?.reference) {
    res.status(200).json({ received: true });
    return;
  }
  const reference = payload.data.reference;
  const orderId = readOrderId(payload.data.metadata);
  if (!orderId) {
    res.status(400).json({ message: "Missing order metadata" });
    return;
  }
  const order = await getOrder(orderId);
  if (!order || order.paystackReference !== reference || !isSuccessfulPaystackPayment(payload.data as { status: string; amount: number; currency: string }, { amountMinor: order.totalMinor, currency: order.currency })) {
    res.status(400).json({ message: "Payment does not match the order" });
    return;
  }
  await fulfillPaystackOrder(order.id, reference);
  res.status(200).json({ received: true });
}
