<script lang="ts">
	import CrosshairOverlay from './CrosshairOverlay.svelte';
	import type { CircuitJSApi } from '$lib/types/circuitjs';
	import { themeDark } from '$stores/theme';

	interface Props {
		initialCircuit?: string;
		storageKey?: string;
		onready?: (api: CircuitJSApi) => void;
	}

	let { initialCircuit = '', storageKey, onready }: Props = $props();

	let iframe = $state<HTMLIFrameElement>(null!);
	let ready = $state(false);
	let simApi = $state<CircuitJSApi | null>(null);
	let saving = $state(false);
	let saveTimeout = $state<ReturnType<typeof setTimeout> | null>(null);
	let isDestroyed = false;
	let lastLoadedCircuit = $state('');
	let lastStorageKey = $state<string | undefined>(undefined);

	function saveToStorage(text: string) {
		if (!storageKey || isDestroyed) return;
		saving = true;
		if (saveTimeout) clearTimeout(saveTimeout);
		saveTimeout = setTimeout(() => {
			if (!isDestroyed && storageKey) {
				localStorage.setItem(storageKey, text);
			}
			saving = false;
			saveTimeout = null;
		}, 1000);
	}

	export function loadCircuitToSim(text: string) {
		if (!simApi) return;
		const trimmed = text?.trim();
		if (!trimmed) return;

		try {
			simApi.importCircuit(trimmed, false);
			simApi.setSimRunning(true);
			simApi.updateCircuit();
		} catch (err) {
			console.error("CircuitEditor: Error loading circuit:", err);
		}
	}

	function initSimulator(apiFromArg?: any) {
		const win = iframe?.contentWindow as any;
		
		// Priority: Object from callback argument, then from window object
		simApi = apiFromArg || (win ? win.CircuitJS1 : null);

		if (simApi) {
			ready = true;

			// Load initial circuit or draft
			let toLoad = initialCircuit;
			if (storageKey) {
				const saved = localStorage.getItem(storageKey);
				if (saved) {
					toLoad = saved;
				}
			}

			if (toLoad) {
				lastLoadedCircuit = toLoad;
				// Give it a bit more time to be completely ready for interaction
				setTimeout(() => {
					loadCircuitToSim(toLoad);
				}, 1000);
			}

			if (onready) onready(simApi);
		} else {
			console.error("CircuitEditor: Could not find CircuitJS1 API object");
		}
	}

	function handleIframeLoad() {
		if (iframe && iframe.contentWindow) {
			const win = iframe.contentWindow as any;
			
			// Define the callback that CircuitJS1 calls internally
			win.oncircuitjsloaded = (api: any) => {
				initSimulator(api);
			};
			
			// Fallback: if already loaded or callback doesn't fire
			setTimeout(() => {
				if (!ready) {
					initSimulator();
				}
			}, 3000);
		}
	}

	// Re-apply if initialCircuit prop changes
	$effect(() => {
		if (simApi && ready && initialCircuit && initialCircuit !== lastLoadedCircuit) {
			lastLoadedCircuit = initialCircuit;
			const saved = storageKey ? localStorage.getItem(storageKey) : null;
			if (!saved) {
				loadCircuitToSim(initialCircuit);
			}
		}
	});

	// Load draft reactively when storageKey is set (fixes delayed auth problem)
	$effect(() => {
		if (storageKey && storageKey !== lastStorageKey) {
			lastStorageKey = storageKey;
			if (!ready || !simApi) return;

			const saved = localStorage.getItem(storageKey);
			if (saved) {
				loadCircuitToSim(saved);
			} else if (initialCircuit) {
				loadCircuitToSim(initialCircuit);
			}
		}
	});

	// Reactively poll to sync auto-save, ensures it gets setup even if storageKey is delayed
	$effect(() => {
		if (simApi && ready && storageKey) {
			const interval = setInterval(() => {
				const currentText = simApi.exportCircuit();
				const saved = localStorage.getItem(storageKey);
				if (currentText && currentText !== saved && currentText.trim().length > 10) {
					saveToStorage(currentText);
				}
			}, 5000);
			return () => clearInterval(interval);
		}
	});

	// Cleanup timers on destroy
	$effect(() => {
		return () => {
			isDestroyed = true;
			if (saveTimeout) {
				clearTimeout(saveTimeout);
				saveTimeout = null;
			}
		};
	});

	export function getCircuitText(): string {
		if (!simApi) return '';
		return simApi.exportCircuit();
	}

	export function setCircuitText(text: string) {
		loadCircuitToSim(text);
	}

	export function getApi(): CircuitJSApi | null {
		return simApi;
	}

	let iframeSrc = $derived(`/circuitjs1/circuitjs.html?whiteBackground=${!$themeDark}`);
</script>

<div class="circuit-container">
	<div class="circuit-wrapper">
		{#if !ready}
			<div class="editor-loading">Memuat Simulator Rangkaian...</div>
		{/if}
		
		<iframe
			bind:this={iframe}
			src={iframeSrc}
			title="Circuit Simulator"
			onload={handleIframeLoad}
			class:visible={ready}
		></iframe>

		{#if ready}
			<CrosshairOverlay {iframe} />
		{/if}

		{#if storageKey && ready}
			<div class="storage-indicator" title={saving ? "Menyimpan draf..." : "Draf tersimpan di browser"}>
				<span class="indicator-icon" class:saving>
					{saving ? '●' : '☁'}
				</span>
				<span class="indicator-text">Auto-save</span>
			</div>
		{/if}
	</div>
</div>

<style>
	.circuit-container {
		display: flex;
		flex-direction: column;
		gap: 8px;
		width: 100%;
	}
	.circuit-wrapper {
		position: relative;
		border: 1px solid var(--color-border);
		border-radius: var(--radius);
		overflow: hidden;
		width: 100%;
		height: 550px;
		background: #fff;
	}
	iframe {
		width: 100%;
		height: 100%;
		border: none;
		opacity: 0;
		transition: opacity 0.3s;
	}
	iframe.visible {
		opacity: 1;
	}
	.editor-loading {
		position: absolute;
		inset: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		color: var(--color-text-muted);
		font-size: 0.85rem;
		background: var(--color-bg-secondary);
		z-index: 1;
	}
	.storage-indicator {
		position: absolute;
		bottom: 8px;
		right: 12px;
		z-index: 10;
		display: flex;
		align-items: center;
		gap: 6px;
		padding: 4px 8px;
		background: var(--color-bg);
		border: 1px solid var(--color-border);
		border-radius: 12px;
		font-size: 0.7rem;
		color: var(--color-text-muted);
		pointer-events: none;
		opacity: 0.8;
		box-shadow: 0 2px 4px rgba(0,0,0,0.1);
	}
	.indicator-icon {
		line-height: 1;
		font-size: 0.8rem;
		color: var(--color-success);
	}
	.indicator-icon.saving {
		color: var(--color-primary);
		animation: pulse 1s infinite;
	}
	@keyframes pulse {
		0% { opacity: 1; }
		50% { opacity: 0.4; }
		100% { opacity: 1; }
	}
	.indicator-text {
		font-weight: 500;
	}

	@media (max-width: 768px) {
		.circuit-wrapper {
			height: 450px;
		}
	}
</style>
