/**
 * Internal dependencies
 */
import { ToneProp } from '../../components/tone-dropdown-control';
import {
	buildInitialMessageForBackendPrompt,
	buildMessageContextForUserPrompt,
	buildMessagesForBackendPrompt,
	buildRelevantContentMessageForBackendPrompt,
} from './backend-prompt';
/**
 * Types & consts
 */
export const PROMPT_TYPE_SUMMARY_BY_TITLE = 'titleSummary' as const;
export const PROMPT_TYPE_CONTINUE = 'continue' as const;
export const PROMPT_TYPE_SIMPLIFY = 'simplify' as const;
export const PROMPT_TYPE_CORRECT_SPELLING = 'correctSpelling' as const;
export const PROMPT_TYPE_GENERATE_TITLE = 'generateTitle' as const;
export const PROMPT_TYPE_MAKE_LONGER = 'makeLonger' as const;
export const PROMPT_TYPE_MAKE_SHORTER = 'makeShorter' as const;
export const PROMPT_TYPE_CHANGE_TONE = 'changeTone' as const;
export const PROMPT_TYPE_SUMMARIZE = 'summarize' as const;
export const PROMPT_TYPE_CHANGE_LANGUAGE = 'changeLanguage' as const;
export const PROMPT_TYPE_USER_PROMPT = 'userPrompt' as const;
export const PROMPT_TYPE_JETPACK_FORM_CUSTOM_PROMPT = 'jetpackFormCustomPrompt' as const;

export const PROMPT_TYPE_LIST = [
	PROMPT_TYPE_SUMMARY_BY_TITLE,
	PROMPT_TYPE_CONTINUE,
	PROMPT_TYPE_SIMPLIFY,
	PROMPT_TYPE_CORRECT_SPELLING,
	PROMPT_TYPE_GENERATE_TITLE,
	PROMPT_TYPE_MAKE_LONGER,
	PROMPT_TYPE_MAKE_SHORTER,
	PROMPT_TYPE_CHANGE_TONE,
	PROMPT_TYPE_SUMMARIZE,
	PROMPT_TYPE_CHANGE_LANGUAGE,
	PROMPT_TYPE_USER_PROMPT,
	PROMPT_TYPE_JETPACK_FORM_CUSTOM_PROMPT,
] as const;

export type PromptTypeProp = ( typeof PROMPT_TYPE_LIST )[ number ];

export type PromptItemProps = {
	role: 'system' | 'user' | 'assistant' | 'jetpack-ai';
	content?: string;
	context?: object;
};

export const delimiter = '````';

type PromptOptionsProps = {
	/*
	 * The content to add to the prompt.
	 */
	content: string;

	/*
	 * The language to translate to. Optional.
	 */
	language?: string;

	/*
	 * The tone to use. Optional.
	 */
	tone?: ToneProp;

	/*
	 * The role of the prompt. Optional.
	 */
	role?: PromptItemProps[ 'role' ];

	/*
	 * The previous messages of the same prompt. Optional.
	 */
	prevMessages?: Array< PromptItemProps >;

	/*
	 * A custom request prompt. Optional.
	 */
	request?: string;
};

export function getJetpackFormCustomPrompt( {
	content,
	request,
}: PromptOptionsProps ): Array< PromptItemProps > {
	if ( ! request ) {
		throw new Error( 'You must provide a custom prompt for the Jetpack Form Custom Prompt' );
	}

	// Use a jetpack-ai expandable message.
	return [
		{
			role: 'jetpack-ai',
			context: {
				type: 'form-ai-extension',
				content,
				request,
			},
		},
	];
}

export type BuildPromptOptionsProps = {
	contentType?: 'generated' | string;
	tone?: ToneProp;
	language?: string;
	fromExtension?: boolean;
};

export type BuildPromptProps = {
	generatedContent?: string;
	allPostContent?: string;
	postContentAbove?: string;
	currentPostTitle?: string;
	type: PromptTypeProp;
	userPrompt?: string;
	isGeneratingTitle?: boolean;
	options: BuildPromptOptionsProps;
};

/**
 * Builds a prompt based on the type of prompt.
 * Meant for use by the block, not the extensions.
 *
 * @param {BuildPromptProps} options - The prompt options.
 * @returns {Array< PromptItemProps >} The prompt.
 * @throws {Error} If the type is not recognized.
 */
export function buildPromptForBlock( {
	generatedContent,
	allPostContent,
	postContentAbove,
	currentPostTitle,
	options,
	type,
	userPrompt,
	isGeneratingTitle,
}: BuildPromptProps ): Array< PromptItemProps > {
	// Get the initial message to build the system prompt.
	const initialMessage = buildInitialMessageForBackendPrompt( type );

	// Get the user messages to complete the prompt.
	const userMessages = buildMessagesForBackendPrompt( {
		generatedContent,
		allPostContent,
		postContentAbove,
		currentPostTitle,
		options,
		type,
		userPrompt,
		isGeneratingTitle,
	} );

	return [ initialMessage, ...userMessages ];
}

export type BuildExtensionPromptProps = {
	blockContent: string;
	options: BuildPromptOptionsProps;
	type: PromptTypeProp;
	userPrompt?: string;
};

/**
 * Builds a prompt based on the type of prompt.
 * Meant for use by the extensions.
 *
 * @param {BuildPromptProps} options - The prompt options.
 * @returns {Array< PromptItemProps >} The prompt.
 * @throws {Error} If the type is not recognized.
 */
export function buildPromptForExtensions( {
	blockContent,
	options,
	type,
	userPrompt,
}: BuildExtensionPromptProps ): Array< PromptItemProps > {
	const messages = [ buildInitialMessageForBackendPrompt( type ) ];

	const relevantContentMessage = buildRelevantContentMessageForBackendPrompt( false, blockContent );

	if ( relevantContentMessage ) {
		messages.push( relevantContentMessage );
	}

	messages.push( {
		role: 'jetpack-ai' as const,
		context: buildMessageContextForUserPrompt( {
			options,
			type,
			userPrompt,
		} ),
	} );

	return messages;
}
