<script lang="ts">
	import { parseColorText, getPlainText } from "./utils";
	import { themeColors } from "$lib/stores/theme";
	import TuiLine from "./TuiLine.svelte";
	import type { GroupLine, TerminalLine } from "./types";

	interface Props {
		line: GroupLine;
		inline?: boolean;
		onButtonClick?: (idx: number, line?: TerminalLine) => void;
		onHoverButton?: (idx: number) => void;
		onLinkClick?: (idx: number) => void;
	}

	let {
		line,
		inline = false,
		onButtonClick = () => {},
		onHoverButton = () => {},
		onLinkClick = () => {},
	}: Props = $props();

	// Get colorMap from current theme
	const colorMap = $derived($themeColors.colorMap);

	// Parse children with current colorMap
	const parsedChildren = $derived(
		(line.children || []).map((child) => {
			const segments = parseColorText(child.content, colorMap);
			return { line: child, segments, plainText: getPlainText(segments) };
		}),
	);

	// Group consecutive inline elements
	const processedChildren = $derived.by(() => {
		const groups: Array<
			| { kind: "single"; index: number; line: TerminalLine }
			| {
					kind: "inline";
					items: Array<{ index: number; line: TerminalLine }>;
			  }
		> = [];
		let i = 0;

		while (i < parsedChildren.length) {
			const child = parsedChildren[i];
			const isInline = child.line.inline || child.line.display === "inline";

			if (isInline) {
				const inlineItems: Array<{
					index: number;
					line: TerminalLine;
				}> = [];
				while (i < parsedChildren.length) {
					const nextChild = parsedChildren[i];
					const nextIsInline =
						nextChild.line.inline || nextChild.line.display === "inline";
					if (!nextIsInline) break;

					inlineItems.push({
						index: i,
						line: nextChild.line,
					});
					i++;
				}
				groups.push({ kind: "inline", items: inlineItems });
			} else {
				groups.push({ kind: "single", index: i, line: child.line });
				i++;
			}
		}
		return groups;
	});

	// Style for the group container
	const groupStyle = $derived(() => {
		const styles: string[] = [];
		// Only apply flex styles if not grid or block
		if (line.display !== "grid" && line.display !== "block") {
			if (line.groupDirection === "column")
				styles.push("flex-direction: column");
			if (line.groupAlign) {
				const alignMap: Record<string, string> = {
					start: "flex-start",
					center: "center",
					end: "flex-end",
					stretch: "stretch",
				};
				styles.push(
					`align-items: ${alignMap[line.groupAlign] || "flex-start"}`,
				);
			}
		}
		if (line.groupGap) styles.push(`gap: ${line.groupGap}`);
		return styles.join("; ");
	});
</script>

<div
	class="tui-group"
	class:inline
	class:grid={line.display === "grid"}
	class:block={line.display === "block"}
	class:expand={line.groupExpand}
	style={groupStyle()}
	id={line.id}
>
	{#each processedChildren as group}
		{#if group.kind === "inline"}
			<div class="tui-inline-group">
				{#each group.items as item}
					<TuiLine
						line={item.line}
						index={item.index}
						segments={parseColorText(item.line.content, colorMap)}
						complete={true}
						showImage={item.line.type === "image"}
						selectedIndex={-1}
						inline={true}
						{onButtonClick}
						{onHoverButton}
						{onLinkClick}
					/>
				{/each}
			</div>
		{:else}
			<TuiLine
				line={group.line}
				index={group.index}
				segments={parseColorText(group.line.content, colorMap)}
				complete={true}
				showImage={group.line.type === "image"}
				selectedIndex={-1}
				inline={false}
				{onButtonClick}
				{onHoverButton}
				{onLinkClick}
			/>
		{/if}
	{/each}
</div>

<style>
	.tui-group {
		display: flex;
		flex-direction: row;
		align-items: flex-start;
		gap: 0.75rem;
		animation: lineSlideIn 0.15s ease-out;
	}

	.tui-group.inline {
		display: inline-flex;
	}

	.tui-group.grid {
		display: grid;
		grid-template-columns: repeat(
			auto-fill,
			minmax(max(200px, calc((100% - 3.75rem) / 5)), 1fr)
		);
		width: 100%;
	}

	.tui-group.block {
		display: block;
		width: 100%;
	}

	.tui-group.expand > :global(*),
	.tui-group.expand > :global(*) > :global(*) {
		flex: 1;
	}

	.tui-group.expand :global(.tui-button) {
		flex: 1;
		width: auto;
	}

	@keyframes lineSlideIn {
		from {
			opacity: 0;
			transform: translateX(-5px);
		}
		to {
			opacity: 1;
			transform: translateX(0);
		}
	}

	@media (max-width: 768px) {
		/* .tui-group.inline removed to allow inline flow on mobile */

		.tui-group.grid {
			grid-template-columns: 1fr;
		}
	}
</style>
