<script lang="ts">
	import { onMount } from 'svelte';
	import type { Editor as EditorType } from '@tiptap/core';

	let {
		content = '',
		onUpdate,
		placeholder = 'Saisissez votre texte...',
		disabled = false
	}: {
		content?: string;
		onUpdate: (html: string) => void;
		placeholder?: string;
		disabled?: boolean;
	} = $props();

	let editorElement: HTMLDivElement;
	let editor: EditorType | null = $state(null);

	onMount(() => {
		initEditor();

		return () => {
			editor?.destroy();
		};
	});

	async function initEditor() {
		const [{ Editor }, { default: StarterKit }, { default: Link }] = await Promise.all([
			import('@tiptap/core'),
			import('@tiptap/starter-kit'),
			import('@tiptap/extension-link')
		]);

		editor = new Editor({
			element: editorElement,
			extensions: [
				StarterKit.configure({
					heading: false,
					codeBlock: false,
					blockquote: false,
					horizontalRule: false,
					code: false
				}),
				Link.configure({
					openOnClick: false,
					HTMLAttributes: {
						rel: 'noopener noreferrer nofollow',
						target: '_blank'
					}
				})
			],
			content,
			editable: !disabled,
			onUpdate: ({ editor: e }) => {
				const html = e.isEmpty ? '' : e.getHTML();
				onUpdate(html);
			},
			editorProps: {
				attributes: {
					class: 'rich-text-content',
					'aria-label': placeholder,
					role: 'textbox',
					'aria-multiline': 'true'
				}
			}
		});
	}

	$effect(() => {
		if (editor && disabled !== undefined) {
			editor.setEditable(!disabled);
		}
	});

	function toggleBold() {
		editor?.chain().focus().toggleBold().run();
	}

	function toggleItalic() {
		editor?.chain().focus().toggleItalic().run();
	}

	function toggleBulletList() {
		editor?.chain().focus().toggleBulletList().run();
	}

	function toggleOrderedList() {
		editor?.chain().focus().toggleOrderedList().run();
	}

	function toggleLink() {
		if (!editor) return;

		if (editor.isActive('link')) {
			editor.chain().focus().unsetLink().run();
			return;
		}

		const url = window.prompt('URL du lien :');
		if (url) {
			editor.chain().focus().setLink({ href: url }).run();
		}
	}
</script>

<div class="rich-text-editor" class:disabled>
	{#if editor && !disabled}
		<div class="toolbar" role="toolbar" aria-label="Formatage du texte">
			<button
				type="button"
				class="toolbar-btn"
				class:active={editor.isActive('bold')}
				onclick={toggleBold}
				title="Gras"
				aria-label="Gras"
				aria-pressed={editor.isActive('bold')}
			>
				<strong>G</strong>
			</button>
			<button
				type="button"
				class="toolbar-btn"
				class:active={editor.isActive('italic')}
				onclick={toggleItalic}
				title="Italique"
				aria-label="Italique"
				aria-pressed={editor.isActive('italic')}
			>
				<em>I</em>
			</button>
			<span class="toolbar-separator" aria-hidden="true"></span>
			<button
				type="button"
				class="toolbar-btn"
				class:active={editor.isActive('bulletList')}
				onclick={toggleBulletList}
				title="Liste à puces"
				aria-label="Liste à puces"
				aria-pressed={editor.isActive('bulletList')}
			>
				<svg viewBox="0 0 20 20" fill="currentColor" width="16" height="16" aria-hidden="true">
					<path
						fill-rule="evenodd"
						d="M3 4a1 1 0 100 2 1 1 0 000-2zm4 0a1 1 0 000 2h10a1 1 0 100-2H7zm0 5a1 1 0 000 2h10a1 1 0 100-2H7zm0 5a1 1 0 000 2h10a1 1 0 100-2H7zM3 9a1 1 0 100 2 1 1 0 000-2zm0 5a1 1 0 100 2 1 1 0 000-2z"
						clip-rule="evenodd"
					/>
				</svg>
			</button>
			<button
				type="button"
				class="toolbar-btn"
				class:active={editor.isActive('orderedList')}
				onclick={toggleOrderedList}
				title="Liste numérotée"
				aria-label="Liste numérotée"
				aria-pressed={editor.isActive('orderedList')}
			>
				<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16" aria-hidden="true">
					<line x1="10" y1="6" x2="21" y2="6" />
					<line x1="10" y1="12" x2="21" y2="12" />
					<line x1="10" y1="18" x2="21" y2="18" />
					<text x="4" y="7.5" font-size="7" font-weight="700" fill="currentColor" stroke="none" text-anchor="middle">1</text>
					<text x="4" y="13.5" font-size="7" font-weight="700" fill="currentColor" stroke="none" text-anchor="middle">2</text>
					<text x="4" y="19.5" font-size="7" font-weight="700" fill="currentColor" stroke="none" text-anchor="middle">3</text>
				</svg>
			</button>
			<span class="toolbar-separator" aria-hidden="true"></span>
			<button
				type="button"
				class="toolbar-btn"
				class:active={editor.isActive('link')}
				onclick={toggleLink}
				title="Lien"
				aria-label="Lien"
				aria-pressed={editor.isActive('link')}
			>
				<svg viewBox="0 0 20 20" fill="currentColor" width="16" height="16" aria-hidden="true">
					<path
						d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z"
					/>
				</svg>
			</button>
		</div>
	{/if}
	<div bind:this={editorElement} class="editor-container"></div>
</div>

<style>
	.rich-text-editor {
		border: 1px solid #d1d5db;
		border-radius: 0.375rem;
		overflow: hidden;
		transition: border-color 0.15s, box-shadow 0.15s;
	}

	.rich-text-editor:focus-within {
		border-color: #3b82f6;
		box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
	}

	.rich-text-editor.disabled {
		opacity: 0.6;
		background: #f9fafb;
	}

	.toolbar {
		display: flex;
		align-items: center;
		gap: 0.125rem;
		padding: 0.375rem;
		border-bottom: 1px solid #e5e7eb;
		background: #f9fafb;
	}

	.toolbar-btn {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 2rem;
		height: 2rem;
		border: none;
		border-radius: 0.25rem;
		background: transparent;
		color: #374151;
		font-size: 0.875rem;
		cursor: pointer;
		transition: background-color 0.15s, color 0.15s;
	}

	.toolbar-btn:hover {
		background: #e5e7eb;
	}

	.toolbar-btn.active {
		background: #dbeafe;
		color: #2563eb;
	}

	.toolbar-separator {
		width: 1px;
		height: 1.25rem;
		background: #d1d5db;
		margin: 0 0.25rem;
	}

	.editor-container {
		min-height: 8rem;
	}

	.editor-container :global(.rich-text-content) {
		padding: 0.75rem;
		min-height: 8rem;
		outline: none;
		font-size: 0.875rem;
		line-height: 1.5;
		color: #374151;
	}

	.editor-container :global(.rich-text-content p) {
		margin: 0 0 0.5rem;
	}

	.editor-container :global(.rich-text-content p:last-child) {
		margin-bottom: 0;
	}

	.editor-container :global(.rich-text-content ul) {
		list-style-type: disc;
		padding-left: 1.5rem;
		margin: 0 0 0.5rem;
	}

	.editor-container :global(.rich-text-content ol) {
		list-style-type: decimal;
		padding-left: 1.5rem;
		margin: 0 0 0.5rem;
	}

	.editor-container :global(.rich-text-content li) {
		margin-bottom: 0.25rem;
	}

	.editor-container :global(.rich-text-content a) {
		color: #2563eb;
		text-decoration: underline;
	}

	.editor-container :global(.rich-text-content strong) {
		font-weight: 600;
	}

	.editor-container :global(.rich-text-content .is-empty::before) {
		content: attr(data-placeholder);
		color: #9ca3af;
		pointer-events: none;
		float: left;
		height: 0;
	}
</style>
