<script lang="ts">
	import Icon from "@iconify/svelte";
	import { getSegmentStyle, getLinePrefix } from "./utils";
	import { handleNavigation } from "./terminal-keyboard";
	import { user } from "$lib/config";
	import TuiButton from "./TuiButton.svelte";
	import TuiLink from "./TuiLink.svelte";
	import TuiCard from "./TuiCard.svelte";
	import TuiProgress from "./TuiProgress.svelte";
	import TuiAccordion from "./TuiAccordion.svelte";
	import TuiTable from "./TuiTable.svelte";
	import TuiTooltip from "./TuiTooltip.svelte";
	import TuiCardGrid from "./TuiCardGrid.svelte";
	import TuiInput from "./TuiInput.svelte";
	import TuiTextarea from "./TuiTextarea.svelte";
	import TuiCheckbox from "./TuiCheckbox.svelte";
	import TuiRadio from "./TuiRadio.svelte";
	import TuiSelect from "./TuiSelect.svelte";
	import TuiToggle from "./TuiToggle.svelte";
	import TuiGroup from "./TuiGroup.svelte";
	import type { TerminalLine, TextSegment } from "./types";

	interface Props {
		line: TerminalLine;
		index: number;
		segments: TextSegment[];
		complete?: boolean;
		showImage?: boolean;
		selectedIndex?: number;
		inline?: boolean;
		showCursor?: boolean;
		onButtonClick?: (idx: number) => void;
		onHoverButton?: (idx: number) => void;
		onLinkClick?: (idx: number) => void;
	}

	let {
		line,
		index,
		segments,
		complete = true,
		showImage = false,
		selectedIndex = -1,
		inline = false,
		showCursor = false,
		onButtonClick = () => {},
		onHoverButton = () => {},
		onLinkClick = () => {},
	}: Props = $props();

	// Component types that have their own wrapper
	const componentTypes = new Set([
		"button",
		"card",
		"cardgrid",
		"progress",
		"accordion",
		"table",
		"input",
		"textarea",
		"checkbox",
		"radio",
		"select",
		"toggle",
		"group",
	]);

	// Types that need special handling
	const isComponent = $derived(componentTypes.has(line.type));
	const isBlank = $derived(line.type === "blank");
	const isDivider = $derived(line.type === "divider");
	const isImage = $derived(line.type === "image");
	const isPrompt = $derived(
		line.type === "command" || line.type === "prompt",
	);
	const isHeader = $derived(line.type === "header");
	const isLink = $derived(line.type === "link");
	const isTooltip = $derived(line.type === "tooltip");
</script>

{#if isBlank}
	{#if inline}<span class="inline-blank"></span>{:else}<div
			class="tui-line blank"
		></div>{/if}
{:else if isDivider}
	<div class="tui-divider" id={line.id}>
		<span class="divider-line"></span>
		{#if line.content}<span class="divider-text">{line.content}</span>{/if}
		<span class="divider-line"></span>
	</div>
{:else if line.type === "button"}
	<TuiButton
		{line}
		{index}
		selected={selectedIndex === index}
		onClick={onButtonClick}
		onHover={onHoverButton}
		{inline}
	/>
{:else if line.type === "link"}
	{#if inline}
		<TuiLink {line} onClick={() => handleNavigation(line)} />
	{:else}
		<div class="tui-line link">
			<TuiLink {line} onClick={() => onLinkClick(index)} />
		</div>
	{/if}
{:else if line.type === "tooltip"}
	{#if inline}<TuiTooltip {line} />{:else}<div class="tui-line">
			<TuiTooltip {line} />
		</div>{/if}
{:else if line.type === "card"}
	<TuiCard {line} {inline} />
{:else if line.type === "cardgrid"}
	<TuiCardGrid {line} {inline} />
{:else if line.type === "progress"}
	<TuiProgress {line} {inline} />
{:else if line.type === "accordion"}
	<TuiAccordion {line} {inline} />
{:else if line.type === "table"}
	<TuiTable {line} {inline} />
{:else if line.type === "input"}
	<TuiInput {line} {inline} />
{:else if line.type === "textarea"}
	<TuiTextarea {line} {inline} />
{:else if line.type === "checkbox"}
	<TuiCheckbox {line} {inline} />
{:else if line.type === "radio"}
	<TuiRadio {line} {inline} />
{:else if line.type === "select"}
	<TuiSelect {line} {inline} />
{:else if line.type === "toggle"}
	<TuiToggle {line} {inline} />
{:else if line.type === "group"}
	<TuiGroup {line} {inline} {onButtonClick} {onHoverButton} {onLinkClick} />
{:else if line.type === "image" && showImage}
	<div class="tui-image" class:inline-image={inline}>
		<img
			src={line.image}
			alt={line.imageAlt || "Image"}
			style="max-width: {line.imageWidth || 300}px"
		/>
		{#if line.content}<span class="image-caption">{line.content}</span>{/if}
	</div>
{:else if line.type === "header"}
	{#if inline}
		<span class="header-text inline-header">
			<Icon icon="mdi:pound" width="20" class="header-icon" />
			{#each segments as seg}{#if seg.icon}<Icon
						icon={seg.icon}
						width="20"
						class="inline-icon"
					/>{:else if getSegmentStyle(seg)}<span
						style={getSegmentStyle(seg)}>{seg.text}</span
					>{:else}{seg.text}{/if}{/each}
		</span>
	{:else}
		<div class="tui-line header" class:complete id={line.id}>
			<span class="content header-text">
				<Icon icon="mdi:pound" width="25" class="header-icon" />
				{#each segments as seg}{#if seg.icon}<Icon
							icon={seg.icon}
							width="25"
							class="inline-icon"
						/>{:else if getSegmentStyle(seg)}<span
							style={getSegmentStyle(seg)}>{seg.text}</span
						>{:else}{seg.text}{/if}{/each}
			</span>
			{#if showCursor}<span class="cursor"></span>{/if}
		</div>
	{/if}
{:else if line.type === "command" || line.type === "prompt"}
	{#if inline}
		<span class="inline-content {line.type}">
			{getLinePrefix(line.type)}{#each segments as seg}{#if seg.icon}<Icon
						icon={seg.icon}
						width="14"
						class="inline-icon"
					/>{:else if getSegmentStyle(seg)}<span
						style={getSegmentStyle(seg)}>{seg.text}</span
					>{:else}{seg.text}{/if}{/each}
		</span>
	{:else}
		<div class="tui-line {line.type}" class:complete id={line.id}>
			<span class="prompt">
				<span class="user">{user.username}</span><span class="at"
					>@</span
				><span class="host">{user.hostname}</span>
				<span class="separator">:</span><span class="path">~</span><span
					class="symbol">$</span
				>
			</span>
			<span class="content">
				{getLinePrefix(
					line.type,
				)}{#each segments as seg}{#if seg.icon}<Icon
							icon={seg.icon}
							width="14"
							class="inline-icon"
						/>{:else if getSegmentStyle(seg)}<span
							style={getSegmentStyle(seg)}>{seg.text}</span
						>{:else}{seg.text}{/if}{/each}
			</span>
			{#if showCursor}<span class="cursor"></span>{/if}
		</div>
	{/if}
{:else if !isImage}
	{#if inline}
		<span class="inline-content {line.type}">
			{getLinePrefix(line.type)}{#each segments as seg}{#if seg.icon}<Icon
						icon={seg.icon}
						width="14"
						class="inline-icon"
					/>{:else if getSegmentStyle(seg)}<span
						style={getSegmentStyle(seg)}>{seg.text}</span
					>{:else}{seg.text}{/if}{/each}
		</span>
	{:else}
		<div class="tui-line {line.type}" class:complete id={line.id}>
			<span class="content">
				{getLinePrefix(
					line.type,
				)}{#each segments as seg}{#if seg.icon}<Icon
							icon={seg.icon}
							width="14"
							class="inline-icon"
						/>{:else if getSegmentStyle(seg)}<span
							style={getSegmentStyle(seg)}>{seg.text}</span
						>{:else}{seg.text}{/if}{/each}
			</span>
			{#if showCursor}<span class="cursor"></span>{/if}
		</div>
	{/if}
{/if}
