/**
 * Individual Customer API
 * GET    - Fetch a single customer
 * PUT    - Update a customer
 * DELETE - Delete a customer
 *
 * All data access goes through Convex. No Prisma fallback.
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { validateCSRFToken } from "@/lib/csrf";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { logger } from "@/lib/logger";
import { convexQuery, convexMutation } from "@/lib/convex-client";
import validator from "validator";

interface RouteParams {
  params: Promise<{ id: string }>;
}

/**
 * Look up the user by email via Convex.
 */
async function findUserByEmail(email: string) {
  const user = await convexQuery<Record<string, unknown>>(
    "auth/queries:getUserByEmail",
    { email },
  );
  if (!user) return null;
  return {
    id:
      (user.prismaId as string) ||
      (user.appUserId as string) ||
      (user._id as string),
    email: user.email as string,
  };
}

/**
 * Get effective owner ID — for org members, return the org owner's user ID.
 */
async function getEffectiveOwnerIdDirect(userId: string): Promise<string> {
  try {
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    );
    if (!orgState) return userId;

    const userRole = orgState.userRole as string | undefined;
    const organization = orgState.organization as
      | Record<string, unknown>
      | undefined;

    if (!organization || userRole === "OWNER") return userId;

    const ownerId = organization.ownerId as string | undefined;
    return ownerId || userId;
  } catch {
    return userId;
  }
}

/**
 * GET /api/user/customers/[id]
 * Returns a single customer by ID via Convex.
 */
export async function GET(request: NextRequest, { params }: RouteParams) {
  try {
    const { id } = await params;
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const user = await findUserByEmail(userEmail);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerIdDirect(user.id);

    const customer = await convexQuery("customers/queries:getCustomerById", {
      id,
      userId: effectiveUserId,
    });

    if (!customer) {
      return NextResponse.json(
        { success: false, error: "Customer not found" },
        { status: 404 },
      );
    }

    return NextResponse.json({ success: true, customer });
  } catch (error) {
    logger.error(
      "Failed to fetch customer",
      error instanceof Error ? error : new Error(String(error)),
    );
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

/**
 * PUT /api/user/customers/[id]
 * Updates a customer via Convex.
 */
export async function PUT(request: NextRequest, { params }: RouteParams) {
  try {
    const { id } = await params;
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // CSRF protection (bypass in development for easier testing)
    if (process.env.NODE_ENV !== "development") {
      const isValidCSRF = validateCSRFToken(request);
      if (!isValidCSRF) {
        return NextResponse.json(
          { success: false, error: "Invalid CSRF token" },
          { status: 403 },
        );
      }
    }

    const user = await findUserByEmail(userEmail);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerIdDirect(user.id);

    // Parse request body
    const body = await request.json();
    const { name, phone, email, notes } = body;

    // Validation
    const errors: string[] = [];
    if (name !== undefined && name.trim().length < 2) {
      errors.push("Name must be at least 2 characters");
    }
    if (phone !== undefined && phone.trim().length < 5) {
      errors.push("Phone number is required");
    }
    if (email && !validator.isEmail(email)) {
      errors.push("Invalid email format");
    }
    if (errors.length > 0) {
      return NextResponse.json(
        { success: false, error: errors.join(", "), errors },
        { status: 400 },
      );
    }

    try {
      const customer = await convexMutation(
        "customers/mutations:updateCustomer",
        {
          id,
          userId: effectiveUserId,
          ...(name !== undefined && { name: name.trim() }),
          ...(phone !== undefined && { phone: phone.trim() }),
          ...(email !== undefined && { email: email?.trim() ?? null }),
          ...(notes !== undefined && { notes: notes?.trim() ?? null }),
        },
      );

      if (!customer) {
        return NextResponse.json(
          { success: false, error: "Customer not found" },
          { status: 404 },
        );
      }

      return NextResponse.json({ success: true, customer });
    } catch (convexErr) {
      if (
        convexErr instanceof Error &&
        convexErr.message.includes("DUPLICATE_PHONE")
      ) {
        return NextResponse.json(
          {
            success: false,
            error: "A customer with this phone number already exists",
          },
          { status: 409 },
        );
      }
      throw convexErr;
    }
  } catch (error) {
    logger.error(
      "Failed to update customer",
      error instanceof Error ? error : new Error(String(error)),
    );
    return NextResponse.json(
      { success: false, error: "Failed to update customer" },
      { status: 500 },
    );
  }
}

/**
 * DELETE /api/user/customers/[id]
 * Deletes a customer via Convex.
 */
export async function DELETE(request: NextRequest, { params }: RouteParams) {
  try {
    const { id } = await params;
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // CSRF protection (bypass in development for easier testing)
    if (process.env.NODE_ENV !== "development") {
      const isValidCSRF = validateCSRFToken(request);
      if (!isValidCSRF) {
        return NextResponse.json(
          { success: false, error: "Invalid CSRF token" },
          { status: 403 },
        );
      }
    }

    const user = await findUserByEmail(userEmail);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const effectiveUserId = await getEffectiveOwnerIdDirect(user.id);

    const result = await convexMutation("customers/mutations:deleteCustomer", {
      id,
      userId: effectiveUserId,
    });

    if (!result) {
      return NextResponse.json(
        { success: false, error: "Customer not found" },
        { status: 404 },
      );
    }

    return NextResponse.json({ success: true, deleted: true });
  } catch (error) {
    logger.error(
      "Failed to delete customer",
      error instanceof Error ? error : new Error(String(error)),
    );
    return NextResponse.json(
      { success: false, error: "Failed to delete customer" },
      { status: 500 },
    );
  }
}
