<!-- @format -->
<script lang="ts">
  import type { EntryTemplateItemDto } from "$lib/backend/templates";
  type AttachmentOption = { id: string; label: string };

  export let isEntryDocument = false;
  export let templatesBusy = false;
  export let templateOptions: EntryTemplateItemDto[] = [];
  export let listMode: "ul" | "ol" | null = null;
  export let attachmentsDisabled = false;

  export let onApplyHeading: (level: number) => void = () => {};
  export let onApplyTemplate: (filePath: string) => void = () => {};
  export let onOpenAttachments: () => void = () => {};
  export let onBold: () => void = () => {};
  export let onItalic: () => void = () => {};
  export let onUnderline: () => void = () => {};
  export let onTag: () => void = () => {};
  export let onLink: () => void = () => {};
  export let onToggleUl: () => void = () => {};
  export let onToggleOl: () => void = () => {};
  export let onCode: () => void = () => {};
  export let onSave: () => void = () => {};
  export let saveBusy = false;
  export let onToggleDictation: () => void = () => {};
  export let dictationActive = false;
  export let dictationBusy = false;
  export let dictationUnavailable = false;

  let headingMenuOpen = false;
  let headingMenuEl: HTMLDivElement | null = null;
  let templateMenuOpen = false;
  let templateMenuEl: HTMLDivElement | null = null;

  function toggleHeadingMenu() {
    headingMenuOpen = !headingMenuOpen;
  }

  function selectHeading(level: number) {
    onApplyHeading(level);
    headingMenuOpen = false;
  }

  function handleHeadingFocusOut(event: FocusEvent) {
    const next = event.relatedTarget as Node | null;
    if (headingMenuEl && next && headingMenuEl.contains(next)) return;
    headingMenuOpen = false;
  }

  function toggleTemplateMenu() {
    if (templatesBusy) return;
    templateMenuOpen = !templateMenuOpen;
  }

  function selectTemplate(filePath: string) {
    onApplyTemplate(filePath);
    templateMenuOpen = false;
  }

  function handleTemplateFocusOut(event: FocusEvent) {
    const next = event.relatedTarget as Node | null;
    if (templateMenuEl && next && templateMenuEl.contains(next)) return;
    templateMenuOpen = false;
  }
</script>

<div class="editor-toolbar">
  <div class="toolbar-group">
    <div
      class="toolbar-select-wrap heading-wrap"
      bind:this={headingMenuEl}
      on:focusout={handleHeadingFocusOut}
    >
      <span class="material-symbols-outlined" aria-hidden="true">title</span>
      <button
        type="button"
        class="heading-trigger"
        aria-label="Heading"
        title="Heading"
        aria-haspopup="listbox"
        aria-expanded={headingMenuOpen}
        on:click={toggleHeadingMenu}
      >
        <span class="material-symbols-outlined" aria-hidden="true"
          >expand_more</span
        >
      </button>
      {#if headingMenuOpen}
        <div class="heading-menu" role="listbox" aria-label="Header size">
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(1)}>H1</button
          >
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(2)}>H2</button
          >
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(3)}>H3</button
          >
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(4)}>H4</button
          >
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(5)}>H5</button
          >
          <button
            type="button"
            class="heading-option"
            on:click={() => selectHeading(6)}>H6</button
          >
        </div>
      {/if}
    </div>
    {#if isEntryDocument}
      <div
        class="toolbar-select-wrap template-wrap"
        bind:this={templateMenuEl}
        on:focusout={handleTemplateFocusOut}
      >
        <span class="material-symbols-outlined" aria-hidden="true"
          >description</span
        >
        <button
          type="button"
          class="template-trigger"
          aria-label="Insert template"
          title="Insert template"
          aria-haspopup="listbox"
          aria-expanded={templateMenuOpen}
          disabled={templatesBusy}
          on:click={toggleTemplateMenu}
        >
          <span class="template-trigger-text"
            >{templatesBusy ? "Loading..." : "Template"}</span
          >
          <span class="material-symbols-outlined" aria-hidden="true"
            >expand_more</span
          >
        </button>
        {#if templateMenuOpen}
          <div class="template-menu" role="listbox" aria-label="Template">
            {#if templateOptions.length === 0}
              <div class="template-empty">No templates</div>
            {:else}
              {#each templateOptions as template}
                <button
                  type="button"
                  class="template-option"
                  on:click={() => selectTemplate(template.filePath)}
                >
                  {template.fileName.replace(/\.template\.md$/i, "")}
                </button>
              {/each}
            {/if}
          </div>
        {/if}
      </div>

      <button
        type="button"
        class="toolbar-btn toolbar-icon-btn"
        on:click={onOpenAttachments}
        disabled={attachmentsDisabled}
        aria-label="Attach item"
        title="Attach item"
      >
        <span class="material-symbols-outlined" aria-hidden="true">add</span>
      </button>
    {/if}
  </div>
  <div class="toolbar-divider" aria-hidden="true"></div>
  <div class="toolbar-group">
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onBold}
      aria-label="Bold"
      title="Bold"
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >format_bold</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onItalic}
      aria-label="Italic"
      title="Italic"
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >format_italic</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onUnderline}
      aria-label="Underline"
      title="Underline"
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >format_underlined</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onTag}
      aria-label="Tag"
      title="Tag [[...]]"
    >
      <span class="material-symbols-outlined" aria-hidden="true">sell</span>
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onLink}
      aria-label="Link"
      title="Link"
    >
      <span class="material-symbols-outlined" aria-hidden="true">link</span>
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      class:is-active={listMode === "ul"}
      on:click={onToggleUl}
      aria-label="Bulleted list"
      title="Bulleted list"
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >format_list_bulleted</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      class:is-active={listMode === "ol"}
      on:click={onToggleOl}
      aria-label="Numbered list"
      title="Numbered list"
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >format_list_numbered</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onCode}
      aria-label="Inline code"
      title="Inline code"
    >
      <span class="material-symbols-outlined" aria-hidden="true">code</span>
    </button>
  </div>
  <div class="toolbar-divider" aria-hidden="true"></div>
  <div class="toolbar-group">
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      class:is-active={dictationActive}
      on:click={onToggleDictation}
      disabled={dictationBusy || dictationUnavailable}
      aria-label={dictationActive ? "Stop dictation" : "Start dictation"}
      title={dictationActive ? "Stop dictation" : "Start dictation"}
    >
      <span class="material-symbols-outlined" aria-hidden="true"
        >{dictationActive ? "mic_off" : "mic"}</span
      >
    </button>
    <button
      type="button"
      class="toolbar-btn toolbar-icon-btn"
      on:click={onSave}
      disabled={saveBusy}
      aria-label="Save now"
      title="Save now"
    >
      <span class="material-symbols-outlined" aria-hidden="true">save</span>
    </button>
  </div>
</div>

<style>
  .editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--border-soft);
    border-radius: 12px;
    background: color-mix(in srgb, var(--surface-1) 90%, var(--zinc-700) 10%);
    box-shadow:
      inset 0 1px 0 color-mix(in srgb, var(--zinc-300) 9%, transparent 91%),
      0 8px 24px color-mix(in srgb, var(--bg-app) 38%, transparent 62%);
    padding: 8px 10px;
    margin: 0 14px;
  }

  .toolbar-group {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
  }

  .toolbar-select-wrap {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: 8px;
    border: 1px solid var(--border-soft);
    background: color-mix(in srgb, var(--surface-2) 92%, var(--zinc-700) 8%);
    color: color-mix(in srgb, var(--text-muted) 86%, var(--text-primary) 14%);
    padding: 0 8px;
    min-height: 30px;
  }

  .toolbar-select-wrap .material-symbols-outlined {
    font-size: 16px;
    line-height: 1;
  }

  .toolbar-divider {
    width: 1px;
    height: 22px;
    background: color-mix(in srgb, var(--border-soft) 78%, transparent 22%);
  }

  .toolbar-btn {
    border-radius: 8px;
    border: 1px solid var(--border-soft);
    background: color-mix(in srgb, var(--surface-2) 92%, var(--zinc-700) 8%);
    color: color-mix(in srgb, var(--text-muted) 86%, var(--text-primary) 14%);
    padding: 6px 10px;
    min-height: 30px;
    font-size: 0.73rem;
    letter-spacing: 0.01em;
    font-weight: 600;
    cursor: pointer;
    transition:
      background-color 120ms ease,
      color 120ms ease,
      border-color 120ms ease,
      transform 120ms ease;
  }

  .toolbar-icon-btn {
    padding: 4px 6px;
    width: 32px;
    min-width: 32px;
    justify-content: center;
    display: inline-flex;
    align-items: center;
  }

  .toolbar-icon-btn .material-symbols-outlined {
    font-size: 17px;
    line-height: 1;
  }

  .heading-wrap {
    padding-right: 6px;
    gap: 3px;
    position: relative;
  }

  .heading-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    min-height: 18px;
    color: var(--text-primary);
    cursor: pointer;
  }

  .heading-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    min-width: 68px;
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background: color-mix(in srgb, var(--surface-1) 94%, var(--bg-editor) 6%);
    padding: 4px;
    display: grid;
    gap: 2px;
    z-index: 20;
  }

  .template-wrap {
    position: relative;
    padding-right: 6px;
    gap: 3px;
  }

  .template-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    min-height: 18px;
    color: var(--text-primary);
    cursor: pointer;
  }

  .template-trigger:disabled {
    opacity: 0.6;
    cursor: default;
  }

  .template-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    min-width: 132px;
    max-width: 260px;
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    background: color-mix(in srgb, var(--surface-1) 94%, var(--bg-editor) 6%);
    padding: 4px;
    display: grid;
    gap: 2px;
    z-index: 20;
  }

  .template-empty {
    padding: 6px 8px;
    font-size: 0.76rem;
    color: var(--text-dim);
  }

  .template-option {
    width: 100%;
    text-align: left;
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 0.76rem;
    color: var(--text-primary);
    cursor: pointer;
  }

  .template-trigger-text {
    display: none;
  }

  .template-option:hover {
    background: var(--bg-hover);
  }

  .heading-option {
    width: 100%;
    text-align: left;
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 0.76rem;
    color: var(--text-primary);
    cursor: pointer;
  }

  .heading-option:hover {
    background: var(--bg-hover);
  }

  .toolbar-btn:hover,
  .toolbar-btn:focus-visible {
    background: color-mix(in srgb, var(--bg-hover) 88%, var(--surface-2) 12%);
    color: var(--text-primary);
    border-color: var(--border-strong);
    transform: translateY(-1px);
  }

  .toolbar-btn:focus-visible {
    outline: none;
  }

  .toolbar-btn.is-active {
    background: color-mix(in srgb, var(--bg-active) 84%, var(--surface-2) 16%);
    border-color: var(--border-strong);
    color: var(--text-primary);
  }

  .toolbar-select-wrap:hover,
  .toolbar-select-wrap:focus-within {
    background: color-mix(in srgb, var(--bg-hover) 88%, var(--surface-2) 12%);
    border-color: var(--border-strong);
  }

  .toolbar-btn:disabled {
    opacity: 0.55;
    cursor: default;
    transform: none;
  }

  @media (max-width: 980px) {
    .editor-toolbar {
      margin: 0 8px;
      padding: 7px 8px;
      gap: 6px;
    }

    .toolbar-divider {
      display: none;
    }
  }
</style>
