/**
 * Parses email addresses from various input formats and combines them with previously parsed emails.
 *
 * Supports: single email, JSON array, comma-separated, or space-separated lists.
 * Note: Function signature follows Commander.js option parsing pattern.
 *
 * @param input - Email input string in any supported format
 * @param previousInput - Previously parsed email addresses to append to
 * @returns Combined array of email addresses
 * @throws {Error} For invalid JSON, non-array JSON, invalid email addresses, or unrecognized format
 *
 * @example
 * parseEmail("user@example.com", []) // ["user@example.com"]
 * parseEmail('["user1@example.com", "user2@example.com"]', []) // ["user1@example.com", "user2@example.com"]
 * parseEmail("user1@example.com, user2@example.com", []) // ["user1@example.com", "user2@example.com"]
 */
export function parseEmail(input: string, previousInput: string[]) {
  let result = previousInput ?? [];

  if (isEmail(input)) {
    result.push(input);
  } else if (input.startsWith("[")) {
    let json;
    try {
      json = JSON.parse(input);
    } catch {
      throw new Error("Invalid JSON format for email list");
    }
    if (!Array.isArray(json)) {
      throw new Error("invalid JSON");
    }
    result = result.concat(json);
  } else if (input.includes(",")) {
    result = result.concat(parseList(input, ","));
  } else if (input.includes(" ")) {
    result = result.concat(parseList(input, " "));
  } else {
    throw new Error("`input` must be a single address, a comma-separated list, or a JSON array");
  }

  return result;
}

function isEmail(input: string) {
  return !!input && !!input.match(/^([\w._+-]+?)@([\w._+-]+?)$/);
}

function parseList(value: string, separator: string) {
  const parts = value
    .split(separator)
    .map((v) => v.trim())
    .filter((v) => !!v.length);
  const invalid = parts.find((v) => !isEmail(v));
  if (invalid) {
    throw new Error(`Invalid email address: ${invalid}`);
  }

  return parts;
}
