import { NextRequest } from "next/server";
import {
  successResponse,
  errorResponse,
  paginationResponse,
  createResponse,
  updateResponse,
  deleteResponse,
} from "./responseHandlers";
import { withErrorHandling, validateRequiredFields } from "./requestHandlers";
import {
  ApiHandler,
  PaginationParams,
  ListFunction,
  CreateFunction,
  UpdateFunction,
  DeleteFunction,
} from "./types";

/**
 * Generic list operation handler
 * @param request NextRequest object
 * @param body Request body
 * @param listFunction The function to call to get the list data
 */
export async function handleListOperation(
  request: NextRequest,
  body: any,
  listFunction: ListFunction
) {
  const page = body.page || 1;
  const size = body.size || 10;
  const orderField = body.orderField || ["uu_id"];
  const orderType = body.orderType || ["asc"];
  const query = body.query || {};
  const response = await listFunction({
    page,
    size,
    orderField,
    orderType,
    query,
  } as PaginationParams);
  return paginationResponse(response.data, response.pagination);
}

/**
 * Generic create operation handler
 * @param request NextRequest object
 * @param body Request body
 * @param createFunction The function to call to create the item
 * @param requiredFields Array of required field names
 */
export async function handleCreateOperation(
  body: any,
  createFunction?: CreateFunction,
  requiredFields: string[] = []
) {
  if (requiredFields.length > 0) {
    const validation = validateRequiredFields(body, requiredFields);
    if (!validation.valid) {
      return errorResponse(validation.error as string, 400);
    }
  }

  if (createFunction) {
    console.log("Body:", body);
    const result = await createFunction(body);
    return createResponse(result);
  }

  return createResponse({
    uuid: Math.floor(Math.random() * 1000),
    ...body,
  });
}

/**
 * Generic update operation handler
 * @param request NextRequest object
 * @param body Request body
 * @param updateFunction The function to call to update the item
 */
export async function handleUpdateOperation(
  request: NextRequest,
  body: any,
  updateFunction?: UpdateFunction
) {
  const uuid = request.nextUrl.searchParams.get("uuid");
  if (!uuid) {
    return errorResponse("UUID not found", 400);
  }
  if (updateFunction) {
    console.log("Body:", body);
    const result = await updateFunction(body, uuid);
    return updateResponse(result);
  }
  return updateResponse(body);
}

/**
 * Generic delete operation handler
 * @param request NextRequest object
 * @param deleteFunction The function to call to delete the item
 */
export async function handleDeleteOperation(
  request: NextRequest,
  deleteFunction?: DeleteFunction
) {
  const uuid = request.nextUrl.searchParams.get("uuid");
  if (!uuid) {
    return errorResponse("UUID not found", 400);
  }

  if (deleteFunction) {
    await deleteFunction(uuid);
  }
  return deleteResponse();
}

/**
 * Create a wrapped list handler with error handling
 * @param listFunction The function to call to get the list data
 */
export function createListHandler(listFunction: ListFunction) {
  return withErrorHandling((request: NextRequest, body: any) =>
    handleListOperation(request, body, listFunction)
  );
}

/**
 * Create a wrapped create handler with error handling
 * @param createFunction The function to call to create the item
 * @param requiredFields Array of required field names
 */
export function createCreateHandler(
  createFunction?: CreateFunction,
  requiredFields: string[] = []
) {
  console.log("Required fields:", requiredFields);
  // This handler only takes the body parameter, not the request
  return withErrorHandling((body: any) => {
    // Ensure we're only passing the actual body data to the create function
    if (body && typeof body === 'object' && body.body) {
      console.log("Extracting body from request body");
      return handleCreateOperation(body.body, createFunction, requiredFields);
    }
    return handleCreateOperation(body, createFunction, requiredFields);
  });
}

/**
 * Create a wrapped update handler with error handling
 * @param updateFunction The function to call to update the item
 */
export function createUpdateHandler(updateFunction?: UpdateFunction) {
  return withErrorHandling((request: NextRequest, body: any) =>
    handleUpdateOperation(request, body, updateFunction)
  );
}

/**
 * Create a wrapped delete handler with error handling
 * @param deleteFunction The function to call to delete the item
 */
export function createDeleteHandler(deleteFunction?: DeleteFunction) {
  return withErrorHandling((request: NextRequest) =>
    handleDeleteOperation(request, deleteFunction)
  );
}
