import type { SearchParamValue } from '../../lib/repo-utils';

export type PullStateFilter = 'open' | 'closed' | 'merged';
export type PullSourceMode = 'branch' | 'patch';

export interface PullFilter {
	state: PullStateFilter;
	author?: string;
	query?: string;
}

const searchParamString = (value: SearchParamValue): string => Array.isArray(value) ? value[0] ?? '' : value ?? '';

export const parsePullFilter = (value: SearchParamValue): PullFilter => {
	const filter: PullFilter = { state: 'open' };
	const tokens = searchParamString(value).split(/\s+/).filter(Boolean);
	const queryTokens: string[] = [];

	for (const token of tokens) {
		if (token === 'state:closed') {
			filter.state = 'closed';
			continue;
		}

		if (token === 'state:merged') {
			filter.state = 'merged';
			continue;
		}

		if (token === 'state:open') {
			filter.state = 'open';
			continue;
		}

		if (token.startsWith('author:')) {
			const author = token.slice('author:'.length).trim();
			if (author) {
				filter.author = author;
			}
			continue;
		}

		queryTokens.push(token);
	}

	const query = queryTokens.join(' ').trim();
	if (query) {
		filter.query = query;
	}

	return filter;
};

export const parsePullStateFilter = (value: SearchParamValue): PullStateFilter => parsePullFilter(value).state;

export const buildPullFilterQuery = (filter: PullFilter): string =>
	[
		filter.query,
		`state:${filter.state}`,
		filter.author ? `author:${filter.author}` : undefined,
	].filter(Boolean).join(' ');

export const parsePastedPatchPrefill = (patch: string): { title: string; body: string } => {
	const subject = /^Subject:\s*(?:\[[^\]]+\]\s*)?(.*)$/im.exec(patch)?.[1]?.trim() ?? '';
	const headerEnd = patch.indexOf('\n---');
	const bodyStart = patch.search(/^Subject:.*$/im);

	if (!subject || bodyStart === -1 || headerEnd === -1 || headerEnd <= bodyStart) {
		return { title: subject, body: '' };
	}

	const afterSubject = patch.slice(bodyStart).replace(/^Subject:.*(?:\r?\n)?/i, '');
	const separator = afterSubject.indexOf('\n---');
	const body = separator === -1 ? '' : afterSubject.slice(0, separator).trim();

	return { title: subject, body };
};
