import type { Writable } from 'node:stream';
import { styleText } from 'node:util';
import { settings } from '@clack/core';
import { type CommonOptions, S_BAR, S_BAR_END, S_BAR_START } from './common.js';

/**
 * The `cancel` function defines an interruption of an interaction
 * and therefore its end.
 *
 * @param title Optional closing message to be displayed.
 * @param opts Additional configuration options.
 *
 * @see https://bomb.sh/docs/clack/packages/prompts/#cancel
 *
 * @example
 * ```ts
 * import { cancel } from '@clack/prompts';
 * import process from 'node:process';
 *
 * cancel('Installation canceled');
 * process.exit(1);
 * ```
 */
export const cancel = (message = '', opts?: CommonOptions) => {
	const output: Writable = opts?.output ?? process.stdout;
	const hasGuide = opts?.withGuide ?? settings.withGuide;
	const prefix = hasGuide ? `${styleText('gray', S_BAR_END)}  ` : '';
	output.write(`${prefix}${styleText('red', message)}\n\n`);
};

/**
 * The `intro` function defines the beginning of an interaction.
 *
 * @param title Optional title to be displayed.
 * @param opts Additional configuration options.
 *
 * @see https://bomb.sh/docs/clack/packages/prompts/#intro
 *
 * @example
 * ```ts
 * import { intro } from '@clack/prompts';
 *
 * intro('Welcome to clack');
 * ```
 */
export const intro = (title = '', opts?: CommonOptions) => {
	const output: Writable = opts?.output ?? process.stdout;
	const hasGuide = opts?.withGuide ?? settings.withGuide;
	const prefix = hasGuide ? `${styleText('gray', S_BAR_START)}  ` : '';
	output.write(`${prefix}${title}\n`);
};

/**
 * The `outro` function defines the end of an interaction.
 *
 * @param title Optional closing message to be displayed.
 * @param opts Additional configuration options.
 *
 * @see https://bomb.sh/docs/clack/packages/prompts/#outro
 *
 * @example
 * ```ts
 * import { outro } from '@clack/prompts';
 *
 * outro('All operations are finished');
 * ```
 */
export const outro = (message = '', opts?: CommonOptions) => {
	const output: Writable = opts?.output ?? process.stdout;
	const hasGuide = opts?.withGuide ?? settings.withGuide;
	const prefix = hasGuide ? `${styleText('gray', S_BAR)}\n${styleText('gray', S_BAR_END)}  ` : '';
	output.write(`${prefix}${message}\n\n`);
};
