<script lang="ts">
  import { renderMarkdown, extractEditorTitle } from "$lib/utils/markdown";

  export let openDocumentId = "";
  export let openDocumentName = "";
  export let openDocumentContent = "";
  export let onDocumentContentChange: (content: string) => void = () => {};

  let markdownText = openDocumentContent;
  let lastOpenDocumentId = openDocumentId;
  export let previewOnly = true;
  let editorInput: HTMLTextAreaElement | null = null;

  function updateDraft(value: string) {
    markdownText = value;
    onDocumentContentChange(value);
  }

  function applyWrap(before: string, after = before) {
    if (!editorInput) return;
    const current = markdownText;
    const start = editorInput.selectionStart ?? 0;
    const end = editorInput.selectionEnd ?? start;
    const selected = current.slice(start, end);
    const insertion = `${before}${selected}${after}`;
    const next = `${current.slice(0, start)}${insertion}${current.slice(end)}`;
    markdownText = next;
    onDocumentContentChange(next);
    queueMicrotask(() => {
      if (!editorInput) return;
      const cursor = start + insertion.length;
      editorInput.focus();
      editorInput.setSelectionRange(cursor, cursor);
    });
  }

  function applyLinePrefix(prefix: string) {
    if (!editorInput) return;
    const current = markdownText;
    const start = editorInput.selectionStart ?? 0;
    const end = editorInput.selectionEnd ?? start;
    const blockStart = current.lastIndexOf("\n", start - 1) + 1;
    const blockEndIndex = current.indexOf("\n", end);
    const blockEnd = blockEndIndex === -1 ? current.length : blockEndIndex;
    const block = current.slice(blockStart, blockEnd);
    const nextBlock = block
      .split("\n")
      .map((line) => `${prefix}${line}`)
      .join("\n");
    const next = `${current.slice(0, blockStart)}${nextBlock}${current.slice(blockEnd)}`;
    markdownText = next;
    onDocumentContentChange(next);
  }

  function applyHeading(level: number) {
    if (!Number.isFinite(level) || level < 1 || level > 6) return;
    applyLinePrefix(`${"#".repeat(level)} `);
  }

  function insertLink() {
    applyWrap("[", "](https://example.com)");
  }

  $: if (openDocumentId !== lastOpenDocumentId) {
    markdownText = openDocumentContent;
    lastOpenDocumentId = openDocumentId;
  }
  $: editorTitle = extractEditorTitle(markdownText, openDocumentName);
  $: renderedHtml = renderMarkdown(markdownText);
</script>

<header class="editor-header">
  <h1>{editorTitle}</h1>
</header>

<section class="editor-surface" class:preview-only={previewOnly}>
  {#if !previewOnly}
    <div class="editor-toolbar">
      <select
        class="toolbar-select"
        aria-label="Header size"
        on:change={(event) => {
          const target = event.currentTarget as HTMLSelectElement;
          const level = Number(target.value);
          if (level) applyHeading(level);
          target.value = "";
        }}
      >
        <option value="">Heading</option>
        <option value="1">H1</option>
        <option value="2">H2</option>
        <option value="3">H3</option>
        <option value="4">H4</option>
        <option value="5">H5</option>
        <option value="6">H6</option>
      </select>
      <button type="button" on:click={() => applyWrap("**")}>Bold</button>
      <button type="button" on:click={() => applyWrap("*")}>Italic</button>
      <button type="button" on:click={insertLink}>Link</button>
      <button type="button" on:click={() => applyLinePrefix("- ")}>UL</button>
      <button type="button" on:click={() => applyLinePrefix("1. ")}>OL</button>
      <button type="button" on:click={() => applyWrap("`")}>Code</button>
    </div>
  {/if}

  <div class="editor-workspace">
    {#if previewOnly}
      <article class="markdown-preview" aria-label="Markdown preview">
        {@html renderedHtml}
      </article>
    {:else}
      <textarea
        bind:this={editorInput}
        class="markdown-input"
        bind:value={markdownText}
        on:input={(event) => updateDraft((event.currentTarget as HTMLTextAreaElement).value)}
        aria-label="Markdown input"
      ></textarea>
    {/if}
  </div>
</section>

<style>
  .editor-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }

  .editor-header h1 {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
  }

  .editor-surface {
    min-height: 0;
    flex: 1;
    border-radius: 10px;
    border: 1px solid var(--border-soft);
    background: var(--surface-1);
    padding: 10px;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: 8px;
  }

  .editor-surface.preview-only {
    grid-template-rows: minmax(0, 1fr);
  }

  .editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background: var(--bg-app);
    padding: 6px;
  }

  .editor-toolbar button {
    border-radius: 6px;
    border: 1px solid var(--border-soft);
    background: var(--surface-2);
    color: var(--text-muted);
    padding: 5px 8px;
    font-size: 0.74rem;
    cursor: pointer;
  }

  .toolbar-select {
    border-radius: 6px;
    border: 1px solid var(--border-soft);
    background: var(--surface-2);
    color: var(--text-muted);
    padding: 5px 8px;
    font-size: 0.74rem;
    cursor: pointer;
  }

  .editor-toolbar button:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
  }

  .toolbar-select:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
  }

  .editor-workspace {
    min-height: 0;
    height: 100%;
    display: block;
  }

  .markdown-input,
  .markdown-preview {
    min-height: 0;
    width: 100%;
    height: 100%;
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background: var(--bg-app);
    color: var(--text-primary);
    padding: 12px;
    font-size: 0.88rem;
    line-height: 1.5;
    overflow: auto;
  }

  .markdown-input {
    display: block;
    resize: none;
  }

  .markdown-input:focus {
    outline: none;
    border-color: var(--border-strong);
  }

  .markdown-preview :global(h1),
  .markdown-preview :global(h2),
  .markdown-preview :global(h3),
  .markdown-preview :global(h4),
  .markdown-preview :global(h5),
  .markdown-preview :global(h6) {
    margin: 0 0 8px;
    color: var(--text-primary);
  }

  .markdown-preview :global(p),
  .markdown-preview :global(blockquote),
  .markdown-preview :global(pre),
  .markdown-preview :global(ul),
  .markdown-preview :global(ol) {
    margin: 0 0 10px;
  }

  .markdown-preview :global(ul),
  .markdown-preview :global(ol) {
    padding-left: 18px;
  }

  .markdown-preview :global(code) {
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    border-radius: 4px;
    padding: 1px 4px;
    font-family: Consolas, "Courier New", monospace;
    font-size: 0.82rem;
  }

  .markdown-preview :global(pre code) {
    display: block;
    padding: 8px;
    white-space: pre-wrap;
  }

  .markdown-preview :global(blockquote) {
    border-left: 3px solid var(--border-strong);
    padding-left: 10px;
    color: var(--text-muted);
  }

  .markdown-preview :global(a) {
    color: var(--text-primary);
    text-decoration: underline;
  }
</style>
