import { h } from 'preact';
import { useState } from 'preact/hooks';
import { v4 as uuid } from 'uuid';
import htm from 'htm';
import { PRESETS } from '../utils/presets.js';
const html = htm.bind(h);
export function Editor({ slides, fontSize, onUpdate, onUpdateFontSize, onPlay, onPlayShuffled }) {
const [draggedIndex, setDraggedIndex] = useState(null);
const [dropTargetIndex, setDropTargetIndex] = useState(null);
const updateSlide = (index, newContent) => {
const newSlides = [...slides];
newSlides[index] = { ...newSlides[index], content: newContent };
onUpdate(newSlides);
};
const addSlide = () => {
onUpdate([...slides, { id: uuid(), content: '' }]);
};
const deleteSlide = (index) => {
const newSlides = slides.filter((_, i) => i !== index);
onUpdate(newSlides);
};
// Drag and Drop handlers
const handleDragStart = (e, index) => {
if (e.target.tagName === 'TEXTAREA' || e.target.tagName === 'BUTTON') {
e.preventDefault(); // Prevent dragging the card when interacting with inputs
return;
}
setDraggedIndex(index);
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("text/plain", String(index));
};
const handleDragOver = (e, index) => {
e.preventDefault();
e.dataTransfer.dropEffect = "move";
if (draggedIndex !== index) {
setDropTargetIndex(index);
}
};
const handleDragLeave = (e) => {
// Optional: clear if leaving the list entirely, but often tricky with child elements
};
const handleDrop = (e, targetIndex) => {
e.preventDefault();
const sourceIndexStr = e.dataTransfer.getData("text/plain");
if (!sourceIndexStr && sourceIndexStr !== '0') return;
const sourceIndex = parseInt(sourceIndexStr, 10);
if (isNaN(sourceIndex) || sourceIndex === targetIndex) {
setDropTargetIndex(null);
return;
}
const newSlides = [...slides];
const [movedItem] = newSlides.splice(sourceIndex, 1);
newSlides.splice(targetIndex, 0, movedItem);
onUpdate(newSlides);
setDraggedIndex(null);
setDropTargetIndex(null);
};
const handleDragEnd = () => {
setDraggedIndex(null);
setDropTargetIndex(null);
};
const handleLoadPreset = (e) => {
const presetId = e.target.value;
if (!presetId) return;
const preset = PRESETS.find(p => p.id === presetId);
if (preset) {
if (confirm('This will replace your current slides. Are you sure?')) {
onUpdate(preset.generate());
}
}
e.target.value = "";
};
return html`
<div class="editor-container">
<div class="editor-header">
<div class="toolbar-row">
<h1>Random Slides</h1>
<div class="controls">
<button class="btn btn-danger" onClick=${() => confirm('Clear all slides?') && onUpdate([{ id: uuid(), content: '' }])}>Clear All</button>
<button class="btn btn-primary" onClick=${onPlay} disabled=${slides.length === 0}>Play</button>
<button class="btn btn-secondary" onClick=${onPlayShuffled} disabled=${slides.length === 0}>Shuffle Play</button>
</div>
</div>
<div class="toolbar-row">
<div class="controls">
<div style="display: flex; align-items: center;">
<label for="font-size" style="margin-right: 5px; font-size: 0.9rem;">Font Size:</label>
<input id="font-size" type="number" value=${fontSize} onInput=${(e) => onUpdateFontSize(Number(e.target.value))} style="width: 60px; padding: 5px;" />
</div>
<div style="display: flex; align-items: center;">
<select onChange=${handleLoadPreset} style="padding: 5px;">
<option value="">Load Preset...</option>
${PRESETS.map(p => html`<option value=${p.id}>${p.name}</option>`)}
</select>
</div>
</div>
</div>
</div>
<div class="slide-list">
${slides.map((slide, index) => html`
<div class="slide-card ${draggedIndex === index ? 'dragging' : ''} ${dropTargetIndex === index ? 'drop-target' : ''}"
draggable="true"
onDragStart=${(e) => handleDragStart(e, index)}
onDragOver=${(e) => handleDragOver(e, index)}
onDrop=${(e) => handleDrop(e, index)}
onDragEnd=${handleDragEnd}
key=${slide.id}>
<div class="card-header">
<span>Slide ${index + 1}</span>
<button class="btn btn-danger" onClick=${() => deleteSlide(index)}>Delete</button>
</div>
<textarea class="slide-input"
value=${slide.content}
onInput=${(e) => updateSlide(index, e.target.value)}
placeholder="# Markdown content here..."></textarea>
</div>
`)}
</div>
<button class="add-slide-btn" onClick=${addSlide}>+ Add Slide</button>
</div>
`;
}