<template>
  <IvySelectInput
    ref="elInputRef"
    v-model="selectedFontFamily"
    :placeholder="'Select font'"
    :clearable="false"
    :disabled="false"
    :multiple="false"
    :class="{ 'is-secondary': isSecondary }"
    :aria-label="props.ariaLabel || getLabel('font_family')"
    @update:model-value="onFontFamilySelected"
  >
    <IvySelectOption
      v-for="font in fonts"
      :key="font.value"
      :value="font.value"
      :label="getLabel(font.labelKey)"
      :class="{ 'is-secondary': isSecondary }"
    >
      <span :style="{ fontFamily: formatFontPreview(font.css) }">{{
        getLabel(font.labelKey)
      }}</span>
    </IvySelectOption>
  </IvySelectInput>
</template>

<script setup lang="ts">
import { Editor } from '@tiptap/vue-3'
import { ref, watch } from 'vue'
import { useLabels } from '@/composables/useLabels'
import {
  DEFAULT_EDITOR_FONT_FAMILY,
  EDITOR_FONT_FAMILIES,
  getEditorFontCss,
  resolveEditorFontOption,
} from '@/views/_components/html-editor/editorFonts'

function formatFontPreview(fontFamily: string): string {
  if (/\s/.test(fontFamily) && !fontFamily.includes(',')) {
    return `"${fontFamily}"`
  }
  return fontFamily
}
const { getLabel } = useLabels()

const isSecondary = ref(true)
const props = defineProps<{
  editor: Editor
  ariaLabel?: string
}>()

const fonts = EDITOR_FONT_FAMILIES
const selectedFontFamily = ref<string>(DEFAULT_EDITOR_FONT_FAMILY)

const isSyncingFromEditor = ref(false)

const syncSelectedFontFromEditor = () => {
  const current = props.editor.getAttributes('textStyle').fontFamily as string | undefined
  const resolved = resolveEditorFontOption(current)
  const next = resolved?.value ?? DEFAULT_EDITOR_FONT_FAMILY

  if (selectedFontFamily.value === next) {
    return
  }

  isSyncingFromEditor.value = true
  selectedFontFamily.value = next
  isSyncingFromEditor.value = false
}

watch(
  () => props.editor,
  (editor, _oldEditor, onCleanup) => {
    if (!editor) {
      return
    }

    syncSelectedFontFromEditor()
    editor.on('selectionUpdate', syncSelectedFontFromEditor)

    onCleanup(() => {
      editor.off('selectionUpdate', syncSelectedFontFromEditor)
    })
  },
  { immediate: true },
)

const onFontFamilySelected = (fontFamily: string) => {
  if (isSyncingFromEditor.value || !fontFamily) {
    return
  }

  const cssValue = getEditorFontCss(fontFamily)
  if (!cssValue) {
    return
  }

  props.editor.chain().focus().setFontFamily(cssValue).run()
}
</script>
