export const camelCaseToDisplay = (camelCaseString: string): string => {
  return (camelCaseString.charAt(0).toUpperCase() + camelCaseString.slice(1)).replace(/([A-Z])/g, ' $1').trim();
};

export const snakeCaseToDisplay = (snakeCaseString: string): string => {
  return snakeCaseString.charAt(0).toUpperCase() + snakeCaseString.slice(1).replace('_', ' ').trim();
};

export const jsonPrettyPrint = (obj: unknown): string => {
  return JSON.stringify(obj, null, 2);
};

export const EmailRegexString =
  '(([^<>()[\\].,;:\\s@\\"]+(\\.[^<>()[\\]\\.,;:\\s@\\"]+)*)|(\\".+\\"))@(([^<>()[\\]\\.,;:\\s@\\"]+\\.)+[^<>()[\\]\\.,;:\\s@\\"]{2,})';

const EmailRegexComplete = new RegExp(`^${EmailRegexString}$`);
export const validateEmail = (email: string): boolean => {
  return EmailRegexComplete.test(email);
};

// Matches canonical RFC 4122-style UUIDs (8-4-4-4-12 hex, case-insensitive).
// Intentionally strict: we want to reject inputs that PostgreSQL would later
// reject with `invalid input syntax for type uuid`, surfacing the boundary as
// a 4xx in our own validators instead of a 500 from the DB driver. Do NOT
// loosen this to a partial match or a "looks UUID-ish" regex — the strictness
// is the contract.
export const UUID_REGEX_STRING = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
const UuidRegexComplete = new RegExp(`^${UUID_REGEX_STRING}$`, 'i');
export const isUuid = (value: unknown): value is string => {
  return typeof value === 'string' && UuidRegexComplete.test(value);
};

export const getNextEntityName = (prefix: string, existingNames: string[], separator = '_') => {
  const cleanName = (name: string) => {
    return (
      name
        // eslint-disable-next-line no-useless-escape
        .replace(/[\[\]\(\)\s]/g, separator)
        .replace(/^a-zA-Z0-9+/g, '')
        .replace(new RegExp(`${separator}+`, 'g'), separator)
    );
  };

  const formattedPrefix = cleanName(prefix);
  const cleanedNames = existingNames.map((name) => cleanName(name.trim()));
  const regex = new RegExp(`^${formattedPrefix}(\\d+)$`);
  const usedIndices: number[] = cleanedNames.map((name) => {
    if (name && regex.test(name)) {
      const matches = name.match(regex);
      const ind = matches && Array.isArray(matches) ? parseInt(matches[1], 10) : 0;
      return Number.isNaN(ind) ? 0 : ind;
    }
    return 0;
  }) as number[];

  const lastIndex = Math.max(...usedIndices, ...[0]);

  return `${formattedPrefix}${lastIndex + 1}`;
};
