import { z } from "zod";
import { nonEmptyStringSchema, salesforceIdSchema } from "@customer-portal/domain/common";

// Salesforce IDs can be 15 or 18 characters (alphanumeric)
// Note: salesforceIdSchema is now imported from domain

/**
 * Ensures that the provided value is a Salesforce Id (15 or 18 chars alphanumeric)
 * Uses Zod schema for validation
 */
export function assertSalesforceId(value: unknown, fieldName: string): string {
  try {
    return salesforceIdSchema.parse(value);
  } catch {
    throw new Error(`Invalid Salesforce id for ${fieldName}`);
  }
}

/**
 * Minimal sanitiser for SOQL string literals – escapes single quotes and backslashes.
 */
export function sanitizeSoqlLiteral(value: string): string {
  return value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'");
}

// Schema for validating SOQL field names
const soqlFieldNameSchema = z
  .string()
  .trim()
  .regex(/^[A-Za-z0-9_.]+$/, "Invalid SOQL field name");

/**
 * Ensures a provided field name is safe for inclusion in SOQL statements.
 */
export function assertSoqlFieldName(value: unknown, fieldName: string): string {
  try {
    return soqlFieldNameSchema.parse(value);
  } catch {
    throw new Error(`Invalid SOQL field name for ${fieldName}`);
  }
}

/**
 * Builds an IN clause for SOQL queries from a list of literal values.
 * Uses Zod schema to validate each value
 */
export function buildInClause(values: string[], contextLabel: string): string {
  if (!Array.isArray(values) || values.length === 0) {
    throw new Error(`No values supplied for ${contextLabel} IN clause`);
  }

  const sanitized = values.map(value => {
    try {
      const validValue = nonEmptyStringSchema.parse(value);
      return `'${sanitizeSoqlLiteral(validValue)}'`;
    } catch {
      throw new Error(`Invalid value provided for ${contextLabel} IN clause`);
    }
  });

  return `(${sanitized.join(", ")})`;
}
