<script lang="ts">
	import { onMount } from 'svelte';
	import { themeColors } from '$lib/stores/theme';
	import { user, terminalSettings } from '$lib/config';
	import { calculateTypeSpeed } from '$lib';
	import '$lib/assets/css/terminal-page.css';

	export type LineType = 'command' | 'output' | 'prompt' | 'error' | 'success' | 'info' | 'image' | 'blank' | 'header';

	export interface TerminalLine {
		type: LineType;
		content: string;
		delay?: number;
		image?: string; // URL for image type
		imageAlt?: string;
		imageWidth?: number; // max width in pixels
	}

	interface Props {
		lines?: TerminalLine[];
		title?: string;
		showHeader?: boolean;
		class?: string;
		onComplete?: () => void;
	}

	let { 
		lines = [], 
		title = 'terminal',
		showHeader = true,
		class: className = '',
		onComplete
	}: Props = $props();

	let displayedLines = $state<{ line: TerminalLine; text: string; complete: boolean; showImage: boolean }[]>([]);
	let currentLineIndex = $state(0);
	let isTyping = $state(false);
	let isComplete = $state(false);
	let terminalElement: HTMLDivElement;

	function sleep(ms: number): Promise<void> {
		return new Promise(resolve => setTimeout(resolve, ms));
	}

	async function typeText() {
		if (lines.length === 0) return;

		isTyping = true;
		await sleep(terminalSettings.startDelay);

		for (let i = 0; i < lines.length; i++) {
			const line = lines[i];
			displayedLines = [...displayedLines, { line, text: '', complete: false, showImage: false }];
			currentLineIndex = i;

			if (line.delay) {
				await sleep(line.delay);
			}

			// Handle different line types
			if (line.type === 'image') {
				// For images, show immediately after a brief pause
				await sleep(100);
				displayedLines[i] = { line, text: line.content, complete: true, showImage: true };
			} else if (line.type === 'blank') {
				// Blank lines are instant
				displayedLines[i] = { line, text: '', complete: true, showImage: false };
			} else if (line.type === 'header') {
				// Headers type out faster
				const typeSpeed = 5;
				for (let j = 0; j <= line.content.length; j++) {
					displayedLines[i] = { 
						line, 
						text: line.content.slice(0, j), 
						complete: j === line.content.length,
						showImage: false
					};
					if (j < line.content.length) await sleep(typeSpeed);
				}
			} else {
				// Calculate typing speed based on content length
				const typeSpeed = calculateTypeSpeed(line.content.length);
				
				// Type out the line character by character
				for (let j = 0; j <= line.content.length; j++) {
					displayedLines[i] = { 
						line, 
						text: line.content.slice(0, j), 
						complete: j === line.content.length,
						showImage: false
					};
					
					// Scroll to bottom
					if (terminalElement) {
						terminalElement.scrollTop = terminalElement.scrollHeight;
					}
					
					if (j < line.content.length) {
						await sleep(typeSpeed);
					}
				}
			}

			displayedLines[i].complete = true;
			
			// Scroll to bottom after each line
			if (terminalElement) {
				terminalElement.scrollTop = terminalElement.scrollHeight;
			}
			
			// Pause between lines
			if (i < lines.length - 1) {
				await sleep(terminalSettings.lineDelay);
			}
		}

		isTyping = false;
		isComplete = true;
		onComplete?.();
	}

	onMount(() => {
		typeText();
	});

	function getLinePrefix(type: LineType): string {
		switch (type) {
			case 'error':
				return '✗ ';
			case 'success':
				return '✓ ';
			case 'info':
				return 'ℹ ';
			default:
				return '';
		}
	}

	function getPromptString(): string {
		return `${user.username}@${user.hostname}`;
	}
</script>

<div 
	class="terminal-page {className}"
	style="
		--terminal-bg: {$themeColors.terminal};
		--terminal-text: {$themeColors.text};
		--terminal-muted: {$themeColors.textMuted};
		--terminal-border: {$themeColors.border};
		--terminal-prompt: {$themeColors.terminalPrompt};
		--terminal-user: {$themeColors.terminalUser};
		--terminal-path: {$themeColors.terminalPath};
		--terminal-primary: {$themeColors.primary};
		--terminal-secondary: {$themeColors.secondary};
		--terminal-accent: {$themeColors.accent};
		--terminal-bg-light: {$themeColors.backgroundLight};
	"
	bind:this={terminalElement}
>
	{#if showHeader}
		<!-- Terminal Header -->
		<div class="terminal-header">
			<div class="terminal-buttons">
				<span class="btn close"></span>
				<span class="btn minimize"></span>
				<span class="btn maximize"></span>
			</div>
			<div class="terminal-title">
				<span class="terminal-icon">🐧</span>
				<span>{getPromptString()}: {title}</span>
			</div>
			<div class="terminal-spacer"></div>
		</div>
	{/if}

	<!-- Terminal Body -->
	<div class="terminal-body">
		{#each displayedLines as { line, text, complete, showImage }, i}
			<div class="terminal-line {line.type}" class:complete>
				{#if line.type === 'command' || line.type === 'prompt'}
					<span class="prompt">
						<span class="user">{user.username}@{user.hostname}</span><span class="separator">:</span><span class="path">~</span><span class="symbol">$</span>
					</span>
				{/if}
				
				{#if line.type === 'image' && showImage}
					<div class="terminal-image">
						<img 
							src={line.image} 
							alt={line.imageAlt || 'Terminal 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'}
					<span class="content header-text">{text}</span>
				{:else if line.type !== 'blank'}
					<span class="content">
						{getLinePrefix(line.type)}{text}
					</span>
				{/if}
				
				{#if terminalSettings.showCursor && i === currentLineIndex && !complete && isTyping && line.type !== 'image' && line.type !== 'blank'}
					<span class="cursor"></span>
				{/if}
			</div>
		{/each}
		
		{#if terminalSettings.showCursor && !isTyping && isComplete}
			<div class="terminal-line prompt">
				<span class="prompt">
					<span class="user">{user.username}@{user.hostname}</span><span class="separator">:</span><span class="path">~</span><span class="symbol">$</span>
				</span>
				<span class="cursor"></span>
			</div>
		{/if}
	</div>
</div>
