<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import { browser } from '$app/environment';

	interface Props {
		name?: string;
		value?: string;
		placeholder?: string;
	}

	let { name = 'content', value = $bindable(''), placeholder = 'Write in Markdown...' }: Props = $props();

	let textareaEl: HTMLTextAreaElement;
	let editor: any = null;

	async function uploadImage(file: File): Promise<string | null> {
		const formData = new FormData();
		formData.append('file', file);

		try {
			const res = await fetch('/api/upload-image', { method: 'POST', body: formData });
			if (!res.ok) throw new Error('Upload failed');
			const { url } = await res.json();
			return url;
		} catch {
			alert('Image upload failed');
			return null;
		}
	}

	function insertImageAtCursor(url: string, altText: string) {
		if (!editor) return;
		const cm = editor.codemirror;
		const pos = cm.getCursor();
		cm.replaceRange(`![${altText}](${url})\n`, pos);
		value = editor.value();
	}

	async function handleFiles(files: FileList | File[]) {
		for (const file of files) {
			if (!file.type.startsWith('image/')) continue;
			const url = await uploadImage(file);
			if (url) insertImageAtCursor(url, file.name.replace(/\.[^.]+$/, ''));
		}
	}

	onMount(async () => {
		if (!browser) return;

		const EasyMDE = (await import('easymde')).default;
		await import('easymde/dist/easymde.min.css');

		editor = new EasyMDE({
			element: textareaEl,
			initialValue: value,
			spellChecker: false,
			autofocus: false,
			placeholder,
			status: ['upload'],
			minHeight: '300px',
			toolbar: [
				'bold', 'italic', 'heading', '|',
				'quote', 'unordered-list', 'ordered-list', '|',
				'link',
				{
					name: 'upload-image',
					action: () => {
						const input = document.createElement('input');
						input.type = 'file';
						input.accept = 'image/*';
						input.multiple = true;
						input.onchange = () => {
							if (input.files) handleFiles(input.files);
						};
						input.click();
					},
					className: 'fa fa-image',
					title: 'Upload Image'
				},
				'table', 'code', '|',
				'preview', 'side-by-side', 'fullscreen', '|',
				'guide'
			],
			sideBySideFullscreen: false
		});

		editor.codemirror.on('change', () => {
			value = editor.value();
		});

		// Drag and drop images
		const cm = editor.codemirror;
		cm.on('drop', (_: any, e: DragEvent) => {
			if (e.dataTransfer?.files?.length) {
				e.preventDefault();
				handleFiles(e.dataTransfer.files);
			}
		});

		// Paste images
		cm.on('paste', (_: any, e: ClipboardEvent) => {
			const items = e.clipboardData?.items;
			if (!items) return;
			const imageFiles: File[] = [];
			for (const item of items) {
				if (item.type.startsWith('image/')) {
					const file = item.getAsFile();
					if (file) imageFiles.push(file);
				}
			}
			if (imageFiles.length > 0) {
				e.preventDefault();
				handleFiles(imageFiles);
			}
		});
	});

	onDestroy(() => {
		if (editor) {
			editor.toTextArea();
			editor = null;
		}
	});
</script>

<div class="markdown-editor">
	<textarea bind:this={textareaEl} id={name}></textarea>
	<input type="hidden" {name} value={value} />
</div>

<style>
	.markdown-editor :global(.EasyMDEContainer) {
		border: none;
	}
	.markdown-editor :global(.EasyMDEContainer .CodeMirror) {
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		font-family: ui-monospace, monospace;
		font-size: 0.875rem;
	}
	.markdown-editor :global(.editor-toolbar) {
		border: 1px solid #d1d5db;
		border-bottom: none;
		border-radius: 0.375rem 0.375rem 0 0;
		opacity: 1;
	}
	.markdown-editor :global(.editor-toolbar button) {
		color: #6b7280 !important;
	}
	.markdown-editor :global(.editor-toolbar button:hover) {
		background: #f3f4f6;
	}
	.markdown-editor :global(.editor-toolbar button.active) {
		background: #e5e7eb;
	}
	.markdown-editor :global(.editor-statusbar) {
		display: none;
	}
	/* Dark mode */
	:global(.dark) .markdown-editor :global(.CodeMirror) {
		background: #374151;
		color: #f3f4f6;
		border-color: #4b5563;
	}
	:global(.dark) .markdown-editor :global(.editor-toolbar) {
		background: #1f2937;
		border-color: #4b5563;
	}
	:global(.dark) .markdown-editor :global(.editor-toolbar button) {
		color: #9ca3af !important;
	}
	:global(.dark) .markdown-editor :global(.editor-toolbar button:hover) {
		background: #374151;
	}
	:global(.dark) .markdown-editor :global(.CodeMirror-cursor) {
		border-color: #f3f4f6;
	}
	:global(.dark) .markdown-editor :global(.editor-preview) {
		background: #374151;
		color: #f3f4f6;
	}
	:global(.dark) .markdown-editor :global(.editor-preview-side) {
		background: #374151;
		color: #f3f4f6;
		border-color: #4b5563;
	}
</style>
