/**
 * Quotation Payments API
 * GET  - List payment history for a quotation
 * POST - Record a manual payment
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { withCSRF } from "@/lib/csrf";
import { logger } from "@/lib/logger";
import {
  getPaymentHistory,
  recordManualPayment,
} from "@/lib/services/quotation-payments.service";
import { manualPaymentSchema } from "@/lib/validators/quotation-payments.validator";
import { getDataSource } from "@/lib/data-source";

const log = logger.scope("QuotationPaymentsAPI");

export async function GET(
  request: NextRequest,
  context: { params: Promise<{ id: string }> },
) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerId(user.userId);
    const { id: quotationId } = await context.params;

    // ── Convex path ──────────────────────────────────────────────────
    if (getDataSource("quotations") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");

        // Verify ownership
        const quotation = await convexQuery(
          "quotations/queries:getByUserAndId",
          { userId: effectiveUserId, quotationId },
        );
        if (!quotation) {
          return NextResponse.json(
            { success: false, error: "Quotation not found" },
            { status: 404 },
          );
        }

        // Fetch payments
        const payments = await convexQuery("quotations/queries:getPayments", {
          quotationId,
        });

        return NextResponse.json({
          success: true,
          payments: (payments as Array<Record<string, unknown>>) ?? [],
        });
      } catch (error) {
        log.warn("[Convex fallback] payments GET:", error);
        // Fall through to Prisma path
      }
    }

    // ── Prisma path ──────────────────────────────────────────────────
    const payments = await getPaymentHistory(effectiveUserId, quotationId);

    if (payments === null) {
      return NextResponse.json(
        { success: false, error: "Quotation not found" },
        { status: 404 },
      );
    }

    return NextResponse.json({ success: true, payments });
  } catch (error) {
    log.error("Failed to get payment history", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

export const POST = withCSRF(
  async (
    request: NextRequest,
    context: { params: Promise<{ id: string }> },
  ) => {
    try {
      const user = await getAuthenticatedUser(request, auth);
      if (!user) {
        return NextResponse.json(
          { success: false, error: "Unauthorized" },
          { status: 401 },
        );
      }

      const effectiveUserId = await getEffectiveOwnerId(user.userId);
      const { id: quotationId } = await context.params;

      const body = await request.json();
      const parsed = manualPaymentSchema.safeParse(body);
      if (!parsed.success) {
        return NextResponse.json(
          {
            success: false,
            error: "Invalid input",
            details: parsed.error.flatten(),
          },
          { status: 400 },
        );
      }

      // ── Convex path ──────────────────────────────────────────────
      if (getDataSource("quotations") === "convex") {
        try {
          const { convexQuery, convexMutation } =
            await import("@/lib/convex-client");

          // Verify ownership
          const quotation = await convexQuery(
            "quotations/queries:getByUserAndId",
            { userId: effectiveUserId, quotationId },
          );
          if (!quotation) {
            return NextResponse.json(
              { success: false, error: "Quotation not found" },
              { status: 404 },
            );
          }

          // Record payment via Convex mutation
          const paymentId = await convexMutation(
            "quotations/mutations:recordPayment",
            {
              quotationId,
              amount: parsed.data.amount,
              method: parsed.data.method,
              reference: parsed.data.reference ?? undefined,
              manualNotes: parsed.data.manualNotes ?? undefined,
              recordedBy: effectiveUserId,
            },
          );

          return NextResponse.json(
            {
              success: true,
              payment: { id: paymentId, ...parsed.data, quotationId },
            },
            { status: 201 },
          );
        } catch (error) {
          log.warn("[Convex fallback] payments POST:", error);
          // Fall through to Prisma path
        }
      }

      // ── Prisma path ────────────────────────────────────────────────
      const payment = await recordManualPayment(
        effectiveUserId,
        quotationId,
        parsed.data,
      );
      return NextResponse.json({ success: true, payment }, { status: 201 });
    } catch (error) {
      const message =
        error instanceof Error ? error.message : "Internal server error";
      const status = message.includes("not found") ? 404 : 500;
      log.error("Failed to record manual payment", error);
      return NextResponse.json({ success: false, error: message }, { status });
    }
  },
);
