/**
 * Quotation Detail API
 * GET - Get single quotation with items
 * PATCH - Update quotation
 * DELETE - Delete quotation
 *
 * Convex-first for all operations.
 */

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 { logger } from "@/lib/logger";
import { ConvexHttpClient } from "convex/browser";

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

type RouteContext = { params: Promise<{ id: string }> };

function getConvexClient(): ConvexHttpClient | null {
  const url = process.env.NEXT_PUBLIC_CONVEX_URL || process.env.CONVEX_URL;
  if (!url) return null;
  return new ConvexHttpClient(url);
}

export async function GET(request: NextRequest, context: RouteContext) {
  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 } = await context.params;
    const client = getConvexClient();
    if (!client) {
      return NextResponse.json(
        { success: false, error: "Convex not configured" },
        { status: 503 },
      );
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const quotation = await (client.query as any)(
      "quotations/queries:getById" as any,
      { id },
    );

    // Verify ownership — same pattern as PATCH/DELETE
    if (!quotation || quotation.userId !== effectiveUserId) {
      return NextResponse.json(
        { success: false, error: "Quotation not found" },
        { status: 404 },
      );
    }

    // Fetch items
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const items = await (client.query as any)(
      "quotations/queries:getItems" as any,
      { quotationId: id },
    );

    // Fetch payments
    let payments: unknown[] = [];
    try {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      payments = await (client.query as any)(
        "quotations/queries:getPayments" as any,
        { quotationId: id },
      );
    } catch {
      // Non-critical
    }

    // Fetch customer if customerId exists
    let customer: unknown = null;
    if (quotation.customerId) {
      try {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        customer = await (client.query as any)(
          "customers/queries:getCustomerById" as any,
          { id: quotation.customerId, userId: effectiveUserId },
        );
      } catch {
        // Non-critical
      }
    }

    return NextResponse.json({
      success: true,
      quotation: { ...quotation, id: quotation._id, items, payments, customer },
    });
  } catch (error) {
    log.error("Failed to get quotation", error);
    return NextResponse.json(
      {
        success: false,
        error: error instanceof Error ? error.message : "Internal server error",
      },
      { status: 500 },
    );
  }
}

export async function PATCH(request: NextRequest, context: RouteContext) {
  // CSRF validation (skip in development)
  if (process.env.NODE_ENV !== "development") {
    const { validateCSRFToken } = await import("@/lib/csrf");
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { error: "Invalid or missing CSRF token" },
        { status: 403 },
      );
    }
  }

  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 } = await context.params;
    const body = await request.json();

    const client = getConvexClient();
    if (!client) {
      return NextResponse.json(
        { success: false, error: "Convex not configured" },
        { status: 503 },
      );
    }

    // Verify ownership
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const existing = await (client.query as any)(
      "quotations/queries:getById" as any,
      { id },
    );
    if (!existing || existing.userId !== effectiveUserId) {
      return NextResponse.json(
        { success: false, error: "Quotation not found" },
        { status: 404 },
      );
    }

    // Build update args
    const updateArgs: Record<string, unknown> = { id };
    if (body.title !== undefined) updateArgs.title = body.title;
    if (body.notes !== undefined) updateArgs.notes = body.notes;
    if (body.status !== undefined) updateArgs.status = body.status;
    if (body.taxRate !== undefined) updateArgs.taxRate = body.taxRate;
    if (body.discountRate !== undefined)
      updateArgs.discountRate = body.discountRate;
    if (body.validUntil !== undefined)
      updateArgs.validUntil = body.validUntil
        ? new Date(body.validUntil).getTime()
        : undefined;

    if (body.customerId !== undefined) updateArgs.customerId = body.customerId;

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    await (client.mutation as any)(
      "quotations/mutations:updateQuotation" as any,
      updateArgs,
    );

    // Handle items update: delete old items, insert new ones
    if (Array.isArray(body.items)) {
      // Delete existing items
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const existingItems = await (client.query as any)(
        "quotations/queries:getItems" as any,
        { quotationId: id },
      );
      for (const item of existingItems || []) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        await (client.mutation as any)(
          "quotations/mutations:removeItem" as any,
          { id: item._id },
        );
      }

      // Insert new items and recalculate totals
      for (let i = 0; i < body.items.length; i++) {
        const item = body.items[i];
        if (!item.description?.trim()) continue;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        await (client.mutation as any)(
          "quotations/mutations:addItem" as any,
          {
            quotationId: id,
            description: item.description,
            quantity: item.quantity || 1,
            unitPrice: item.unitPrice || 0,
            sortOrder: i,
          },
        );
      }
    }

    return NextResponse.json({ success: true });
  } catch (error) {
    log.error("Failed to update quotation", error);
    return NextResponse.json(
      {
        success: false,
        error: error instanceof Error ? error.message : "Internal server error",
      },
      { status: 500 },
    );
  }
}

export async function DELETE(request: NextRequest, context: RouteContext) {
  // CSRF validation (skip in development)
  if (process.env.NODE_ENV !== "development") {
    const { validateCSRFToken } = await import("@/lib/csrf");
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { error: "Invalid or missing CSRF token" },
        { status: 403 },
      );
    }
  }

  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 } = await context.params;

    const client = getConvexClient();
    if (!client) {
      return NextResponse.json(
        { success: false, error: "Convex not configured" },
        { status: 503 },
      );
    }

    // Verify ownership
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const existing = await (client.query as any)(
      "quotations/queries:getById" as any,
      { id },
    );
    if (!existing || existing.userId !== effectiveUserId) {
      return NextResponse.json(
        { success: false, error: "Quotation not found" },
        { status: 404 },
      );
    }

    // Delete items first, then quotation
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const items = await (client.query as any)(
      "quotations/queries:getItems" as any,
      { quotationId: id },
    );
    for (const item of items || []) {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      await (client.mutation as any)(
        "quotations/mutations:removeItem" as any,
        { id: item._id },
      );
    }

    // Delete the quotation itself — need a delete mutation
    // For now, mark as CANCELLED
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    await (client.mutation as any)(
      "quotations/mutations:updateQuotation" as any,
      { id, status: "CANCELLED" },
    );

    return NextResponse.json({ success: true });
  } catch (error) {
    log.error("Failed to delete quotation", error);
    return NextResponse.json(
      {
        success: false,
        error: error instanceof Error ? error.message : "Internal server error",
      },
      { status: 500 },
    );
  }
}
