/**
 * Viewport calculations for sticky-bottom scrolling in the differential TUI renderer.
 *
 * Purpose: isolate arithmetic used by sticky-bottom scrolling so behaviour stays
 * explicit and easier to regression-test.
 */

/**
 * Whether the bottom of the content is visible in the working viewport (`TUI.isAtBottom`).
 */
export function isStickyViewportAtBottom(params: {
	maxLinesRendered: number;
	terminalRows: number;
	previousContentLineCount: number;
}): boolean {
	const { maxLinesRendered, terminalRows, previousContentLineCount } = params;
	const height = terminalRows;
	const viewportTop = Math.max(0, maxLinesRendered - height);
	const viewportBottom = viewportTop + height;
	return viewportBottom >= previousContentLineCount;
}

/**
 * CSI escapes to reposition the cursor vertically for sticky-bottom (`TUI.scrollToBottom`).
 */
export function buildStickyScrollVerticalEscapes(params: {
	contentLineCount: number;
	terminalRows: number;
	previousViewportTop: number;
	hardwareCursorRow: number;
}): { escapes: string; nextPreviousViewportTop: number } | null {
	const {
		contentLineCount,
		terminalRows,
		previousViewportTop,
		hardwareCursorRow,
	} = params;
	const height = terminalRows;

	if (contentLineCount <= height) {
		return null;
	}

	const viewportTop = Math.max(0, contentLineCount - height);
	const targetScreenRow = contentLineCount - 1;
	const currentScreenRow = hardwareCursorRow - previousViewportTop;
	const lineDiff = targetScreenRow - currentScreenRow;

	let escapes = "";
	if (lineDiff > 0) {
		escapes += `\x1b[${lineDiff}B`;
	} else if (lineDiff < 0) {
		escapes += `\x1b[${-lineDiff}A`;
	}

	return { escapes, nextPreviousViewportTop: viewportTop };
}
