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

	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-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>

<style>
	.terminal-page {
		font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
		background: var(--terminal-bg);
		border: 1px solid var(--terminal-border);
		border-radius: 12px;
		overflow: hidden;
		box-shadow: 
			0 25px 50px -12px rgba(0, 0, 0, 0.4),
			0 0 0 1px rgba(255, 255, 255, 0.05) inset;
		animation: terminalFadeIn 0.5s ease-out;
		display: flex;
		flex-direction: column;
		height: 100%;
	}

	@keyframes terminalFadeIn {
		from {
			opacity: 0;
			transform: translateY(20px) scale(0.98);
		}
		to {
			opacity: 1;
			transform: translateY(0) scale(1);
		}
	}

	.terminal-header {
		display: flex;
		align-items: center;
		padding: 0.75rem 1rem;
		background: var(--terminal-bg-light);
		border-bottom: 1px solid var(--terminal-border);
		flex-shrink: 0;
	}

	.terminal-buttons {
		display: flex;
		gap: 8px;
	}

	.terminal-buttons .btn {
		width: 12px;
		height: 12px;
		border-radius: 50%;
		cursor: pointer;
		transition: opacity 0.2s;
	}

	.terminal-buttons .btn:hover {
		opacity: 0.8;
	}

	.terminal-buttons .close {
		background: #ff5f56;
	}

	.terminal-buttons .minimize {
		background: #ffbd2e;
	}

	.terminal-buttons .maximize {
		background: #27ca40;
	}

	.terminal-title {
		flex: 1;
		text-align: center;
		font-size: 0.8rem;
		color: var(--terminal-muted);
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.5rem;
	}

	.terminal-icon {
		font-size: 1rem;
	}

	.terminal-spacer {
		width: 52px;
	}

	.terminal-body {
		padding: 1rem 1.25rem;
		flex: 1;
		overflow-y: auto;
		font-size: 0.9rem;
		line-height: 1.6;
	}

	.terminal-line {
		display: flex;
		align-items: flex-start;
		flex-wrap: wrap;
		margin-bottom: 0.25rem;
		animation: lineSlideIn 0.2s ease-out;
		min-height: 1.6em;
	}

	.terminal-line.blank {
		min-height: 0.8em;
	}

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

	.prompt {
		display: inline-flex;
		margin-right: 0.5rem;
		flex-shrink: 0;
	}

	.prompt .user {
		color: var(--terminal-user);
	}

	.prompt .separator {
		color: var(--terminal-text);
	}

	.prompt .path {
		color: var(--terminal-path);
	}

	.prompt .symbol {
		color: var(--terminal-text);
		margin-left: 0.25rem;
	}

	.content {
		color: var(--terminal-text);
		word-break: break-word;
		white-space: pre-wrap;
	}

	.terminal-line.output .content {
		color: var(--terminal-muted);
	}

	.terminal-line.error .content {
		color: #f38ba8;
	}

	.terminal-line.success .content {
		color: #a6e3a1;
	}

	.terminal-line.info .content {
		color: var(--terminal-primary);
	}

	.terminal-line.header .content {
		color: var(--terminal-accent);
		font-weight: 600;
		font-size: 1rem;
	}

	.header-text {
		color: var(--terminal-accent);
		font-weight: 600;
	}

	.terminal-image {
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
		padding: 0.5rem 0;
	}

	.terminal-image img {
		border-radius: 8px;
		border: 1px solid var(--terminal-border);
		background: var(--terminal-bg-light);
		object-fit: contain;
	}

	.image-caption {
		color: var(--terminal-muted);
		font-size: 0.8rem;
		font-style: italic;
	}

	.cursor {
		display: inline-block;
		width: 8px;
		height: 1.2em;
		background: var(--terminal-primary);
		animation: cursorBlink 1s step-end infinite;
		margin-left: 2px;
		vertical-align: middle;
	}

	@keyframes cursorBlink {
		0%, 100% { opacity: 1; }
		50% { opacity: 0; }
	}

	/* Scrollbar styling */
	.terminal-body::-webkit-scrollbar {
		width: 8px;
	}

	.terminal-body::-webkit-scrollbar-track {
		background: transparent;
	}

	.terminal-body::-webkit-scrollbar-thumb {
		background: var(--terminal-border);
		border-radius: 4px;
	}

	.terminal-body::-webkit-scrollbar-thumb:hover {
		background: var(--terminal-muted);
	}
</style>
