import crypto from 'crypto';
import prompts from 'prompts';
import ora from 'ora';
import chalk from 'chalk';

// Generates a stable identifier based on the app URL (and optionally name).
// When name is provided it is included in the hash so two apps wrapping
// the same URL can coexist. Omitting name preserves backward compatibility
// with identifiers generated before V3.10.1.
export function getIdentifier(url: string, name?: string) {
  const hashInput = name ? `${url}::${name}` : url;
  const postFixHash = crypto
    .createHash('md5')
    .update(hashInput)
    .digest('hex')
    .substring(0, 6);
  return `com.pake.a${postFixHash}`;
}

export function resolveIdentifier(
  url: string,
  explicitName: string | undefined,
  customIdentifier?: string,
) {
  const trimmedIdentifier = customIdentifier?.trim();
  if (trimmedIdentifier) {
    if (!/^[a-zA-Z][a-zA-Z0-9.-]*[a-zA-Z0-9]$/.test(trimmedIdentifier)) {
      throw new Error(
        `Invalid identifier "${trimmedIdentifier}". Must start with a letter, ` +
          `contain only letters, digits, hyphens, and dots, and end with a letter or digit.`,
      );
    }
    return trimmedIdentifier;
  }

  return getIdentifier(url, explicitName);
}

export async function promptText(
  message: string,
  initial?: string,
): Promise<string> {
  const response = await prompts({
    type: 'text',
    name: 'content',
    message,
    initial,
  });
  return response.content;
}

export function capitalizeFirstLetter(string: string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

export function getSpinner(text: string) {
  const loadingType = {
    interval: 80,
    frames: ['✦', '✶', '✺', '✵', '✸', '✹', '✺'],
  };
  return ora({
    text: `${chalk.cyan(text)}\n`,
    spinner: loadingType,
    color: 'cyan',
  }).start();
}
