/**
 * Base Adapter Utilities — Convex ↔ Prisma Shape Translation
 *
 * Provides shared utilities for domain adapters that route between
 * Prisma and Convex backends based on the data-source router.
 */

// Types for Convex documents (they have _id and _creationTime)
export interface ConvexDoc {
  _id: string;
  _creationTime: number;
  [key: string]: unknown;
}

/**
 * Convert a single Convex document to Prisma-compatible shape:
 * - _id → id (string)
 * - numeric timestamps → Date objects
 * - Strip _creationTime
 */
export function convexToPrismaShape<T extends Record<string, unknown>>(
  doc: ConvexDoc,
  timestampFields: string[] = [
    "createdAt",
    "updatedAt",
    "readAt",
    "resolvedAt",
  ],
): T {
  const { _id, _creationTime, prismaId, ...rest } = doc;

  const result: Record<string, unknown> = {
    ...rest,
    id: (prismaId as string) || _id,
  };

  // Convert epoch-ms timestamps to Date objects
  for (const field of timestampFields) {
    if (result[field] != null && typeof result[field] === "number") {
      result[field] = new Date(result[field] as number);
    }
    // If field is explicitly null/undefined, keep as null
    if (result[field] === undefined) {
      result[field] = null;
    }
  }

  return result as T;
}

/**
 * Convert an array of Convex documents to Prisma-compatible shapes.
 */
export function convexToPrismaShapeMany<T extends Record<string, unknown>>(
  docs: ConvexDoc[],
  timestampFields?: string[],
): T[] {
  return docs.map((doc) => convexToPrismaShape<T>(doc, timestampFields));
}

/**
 * Convert a Date (or Date-like value) to Convex epoch-ms timestamp.
 */
export function dateToConvexTimestamp(
  date: Date | string | number | null | undefined,
): number | undefined {
  if (date == null) return undefined;
  if (date instanceof Date) return date.getTime();
  if (typeof date === "string") return new Date(date).getTime();
  if (typeof date === "number") return date;
  return undefined;
}

/**
 * Extract basic equality filters from a Prisma-style where clause.
 * Returns flat key-value pairs for simple equality conditions.
 * Complex conditions (in, gt, lt, etc.) return the raw value for caller handling.
 */
export function extractSimpleFilters(
  where: Record<string, unknown> | undefined,
): Record<string, unknown> {
  if (!where) return {};
  const filters: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(where)) {
    if (value === undefined) continue;
    // Simple equality
    if (typeof value !== "object" || value === null || value instanceof Date) {
      filters[key] = value;
    }
    // Pass through complex filters for caller handling
    else {
      filters[key] = value;
    }
  }
  return filters;
}

/**
 * Apply skip/take pagination to an already-fetched array.
 * Convex doesn't support skip natively, so we over-fetch and slice.
 */
export function applyPagination<T>(
  items: T[],
  skip?: number,
  take?: number,
): T[] {
  let result = items;
  if (skip && skip > 0) {
    result = result.slice(skip);
  }
  if (take && take > 0) {
    result = result.slice(0, take);
  }
  return result;
}

/**
 * Type for Prisma-compatible batch operation results.
 */
export interface BatchResult {
  count: number;
}
