import { NextRequest, NextResponse } from "next/server";
import { requireStaffAuth } from "@/lib/staff-auth";
import { prisma } from "@/lib/db";
import { cancelRefund } from "@/lib/stripe";
import { createId } from "@paralleldrive/cuid2";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";
import { convexQuery, convexMutation } from "@/lib/convex-client";

/**
 * POST /api/staff/dashboard/refunds/[id]/cancel
 * Cancel a pending refund
 */
export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const user = await requireStaffAuth();
    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Only ADMIN or SUPER_ADMIN can cancel refunds
    if (user.role !== "ADMIN" && user.role !== "SUPER_ADMIN") {
      return NextResponse.json(
        { error: "Insufficient permissions to cancel refunds" },
        { status: 403 },
      );
    }

    const { id } = await params;

    // --- Convex path (Stripe cancel stays as-is, only DB state routes) ---
    if (getDataSource("billing") === "convex") {
      try {
        // Get the refund from Convex to find stripeRefundId
        const convexRefund = (await convexQuery(
          (api.billing.queries as any).getRefundById,
          { refundId: id },
        )) as any;

        if (!convexRefund) {
          return NextResponse.json(
            { error: "Refund not found" },
            { status: 404 },
          );
        }

        if (convexRefund.status !== "pending") {
          return NextResponse.json(
            {
              error: `Cannot cancel refund with status: ${convexRefund.status}. Only pending refunds can be cancelled.`,
            },
            { status: 400 },
          );
        }

        // Cancel in Stripe (stays as-is)
        const cancelledRefund = await cancelRefund(convexRefund.stripeRefundId);
        if (!cancelledRefund) {
          return NextResponse.json(
            {
              error:
                "Failed to cancel refund in Stripe. The refund may have already been processed.",
            },
            { status: 400 },
          );
        }

        // Update status in Convex
        await convexMutation((api.billing.mutations as any).cancelRefund, {
          stripeRefundId: convexRefund.stripeRefundId,
        });

        // Record billing history
        await convexMutation("billing/mutations:recordPayment", {
          customerId: convexRefund.customerId,
          subscriptionId: convexRefund.subscriptionId || undefined,
          event: "refund_cancelled",
          amount: convexRefund.amount,
          currency: convexRefund.currency,
          metadata: {
            refund_id: convexRefund.stripeRefundId,
            cancelled_by_staff_id: user.id,
            cancelled_by_staff_name: user.name,
            original_reason: convexRefund.reason || "not_specified",
          },
        });

        logger.info("Refund cancelled via Convex", {
          refundId: id,
          stripeRefundId: convexRefund.stripeRefundId,
          cancelledBy: user.id,
        });

        return NextResponse.json({
          success: true,
          refund: {
            id: convexRefund._id,
            stripeRefundId: convexRefund.stripeRefundId,
            status: "canceled",
            updatedAt: new Date().toISOString(),
          },
          message: "Refund cancelled successfully",
        });
      } catch (convexErr: any) {
        if (convexErr.type === "StripeInvalidRequestError") {
          return NextResponse.json(
            { error: convexErr.message || "Cannot cancel this refund" },
            { status: 400 },
          );
        }
        console.error(
          "Convex cancel refund failed, falling back to Prisma:",
          convexErr,
        );
      }
    }

    // --- Prisma path ---
    // Find the refund
    const refund = await prisma.refunds.findUnique({
      where: { id },
    });

    if (!refund) {
      return NextResponse.json({ error: "Refund not found" }, { status: 404 });
    }

    // Check if refund can be cancelled (only pending refunds)
    if (refund.status !== "pending") {
      return NextResponse.json(
        {
          error: `Cannot cancel refund with status: ${refund.status}. Only pending refunds can be cancelled.`,
        },
        { status: 400 },
      );
    }

    // Cancel refund in Stripe
    const cancelledRefund = await cancelRefund(refund.stripeRefundId);

    if (!cancelledRefund) {
      return NextResponse.json(
        {
          error:
            "Failed to cancel refund in Stripe. The refund may have already been processed.",
        },
        { status: 400 },
      );
    }

    // Update status in both databases
    const updatedRefund = await updateRefundStatus(
      refund.stripeRefundId,
      "canceled",
    );

    // Create billing history entry for cancellation
    const billingHistoryId = createId();

    logger.info("Refund cancelled successfully", {
      refundId: refund.id,
      stripeRefundId: refund.stripeRefundId,
      cancelledBy: user.id,
    });

    return NextResponse.json({
      success: true,
      refund: {
        id: updatedRefund.id,
        stripeRefundId: updatedRefund.stripeRefundId,
        status: updatedRefund.status,
        updatedAt: updatedRefund.updatedAt.toISOString(),
      },
      message: "Refund cancelled successfully",
    });
  } catch (error: any) {
    logger.error("Failed to cancel refund:", { error: error.message });

    // Handle Stripe-specific errors
    if (error.type === "StripeInvalidRequestError") {
      return NextResponse.json(
        { error: error.message || "Cannot cancel this refund" },
        { status: 400 },
      );
    }

    return NextResponse.json(
      { error: "Failed to cancel refund" },
      { status: 500 },
    );
  }
}
