import { truncateToWidth, visibleWidth } from "@singularity-forge/tui";

const RESET = "\x1b[0m";
function fgCode(color) {
	switch (color) {
		case "black":
			return "30";
		case "red":
			return "31";
		case "green":
			return "32";
		case "yellow":
			return "33";
		case "blue":
			return "34";
		case "magenta":
			return "35";
		case "cyan":
			return "36";
		case "white":
			return "37";
		case "brightBlack":
			return "90";
		case "brightRed":
			return "91";
		case "brightGreen":
			return "92";
		case "brightYellow":
			return "93";
		case "brightBlue":
			return "94";
		case "brightMagenta":
			return "95";
		case "brightCyan":
			return "96";
		case "brightWhite":
			return "97";
		default:
			return "39";
	}
}
function bgCode(color) {
	switch (color) {
		case "black":
			return "40";
		case "red":
			return "41";
		case "green":
			return "42";
		case "yellow":
			return "43";
		case "blue":
			return "44";
		case "magenta":
			return "45";
		case "cyan":
			return "46";
		case "white":
			return "47";
		case "brightBlack":
			return "100";
		case "brightRed":
			return "101";
		case "brightGreen":
			return "102";
		case "brightYellow":
			return "103";
		case "brightBlue":
			return "104";
		case "brightMagenta":
			return "105";
		case "brightCyan":
			return "106";
		case "brightWhite":
			return "107";
		default:
			return "49";
	}
}
function ansi(fg, bg, bold) {
	const codes = [];
	if (bold) codes.push("1");
	if (fg) codes.push(fgCode(fg));
	if (bg) codes.push(bgCode(bg));
	return codes.length ? `\x1b[${codes.join(";")}m` : RESET;
}
export function renderPowerline(segments, width, theme) {
	if (!segments.length) return "";
	const SEP = "";
	const _SEP_WIDTH = visibleWidth(SEP);
	// Build raw segments with separators
	const parts = [];
	for (let i = 0; i < segments.length; i++) {
		const seg = segments[i];
		const next = segments[i + 1];
		const text = ` ${seg.text} `;
		const segAnsi = ansi(seg.fg, seg.bg, seg.bold);
		parts.push(segAnsi + text);
		if (next) {
			// Separator uses current bg as fg, next bg as bg
			const sepAnsi = ansi(seg.bg, next.bg, false);
			parts.push(sepAnsi + SEP);
		} else {
			// Final separator: current bg as fg, default bg
			const sepAnsi = ansi(seg.bg, undefined, false);
			parts.push(sepAnsi + SEP);
		}
	}
	const line = parts.join("") + RESET;
	const vis = visibleWidth(line);
	// If too wide, drop non-essential segments from the right
	if (vis > width && segments.length > 2) {
		const trimmed = segments.slice(0, -1);
		return renderPowerline(trimmed, width, theme);
	}
	if (vis > width) return truncateToWidth(line, width, "");
	// Pad right to fill width
	if (vis < width) {
		return line + " ".repeat(width - vis) + RESET;
	}
	return line;
}
export function renderPowerlineRight(segments, width, theme) {
	if (!segments.length) return "";
	const SEP = "";
	// Build right-to-left
	const parts = [];
	// Start separator: default bg -> first segment bg
	const first = segments[0];
	parts.push(
		ansi(first.bg, undefined, false) +
			SEP +
			ansi(first.fg, first.bg, first.bold) +
			` ${first.text} `,
	);
	for (let i = 1; i < segments.length; i++) {
		const seg = segments[i];
		const prev = segments[i - 1];
		parts.push(
			ansi(prev.bg, seg.bg, false) +
				SEP +
				ansi(seg.fg, seg.bg, seg.bold) +
				` ${seg.text} `,
		);
	}
	const line = parts.join("") + RESET;
	const vis = visibleWidth(line);
	if (vis > width && segments.length > 1) {
		const trimmed = segments.slice(1);
		return renderPowerlineRight(trimmed, width, theme);
	}
	if (vis > width) return truncateToWidth(line, width, "");
	if (vis < width) {
		return " ".repeat(width - vis) + line + RESET;
	}
	return line;
}
