<template>
  <div :class="['form-item', half ? 'form-item-half' : '', elclass || '']">
    <span class="form-item-title" v-if="title !== undefined && title !== ''">
      {{ title }}
    </span>
    <slot name="input">
      <label>
        <span v-if="label !== undefined && label !== ''">
          {{ label }}
          <i v-if="required" class="form-item-alert">*</i>
        </span>
        <div :ref="'quillContainer' + rnd"></div>
        <span
          class="form-item-alert"
          v-if="InvalidMessages.length > 0 && InvalidMessages !== ''">
          {{ InvalidMessages }}
        </span>
        <span
          class="form-item-description"
          v-if="description !== undefined && description !== ''">
          {{ description }}
        </span>
      </label>
    </slot>
  </div>
</template>
<script setup lang="ts">
  import { ref, reactive, computed, onMounted, useTemplateRef, watch } from 'vue'
  import Quill from 'quill'
  import 'quill/dist/quill.snow.css'

  declare const window: any

  window.Quill = Quill

  export interface Props {
    label?: string
    disabled?: boolean
    modelValue: string
    half?: boolean
    title?: string
    invalidText?: string
    description?: string
    placeholder?: string
    required?: boolean
    maxlength?: string
    minlength?: string
    iclass?: string
    elclass?: string
    modelKey?: string
  }
  const props = withDefaults(defineProps<Props>(), {
    disabled: false,
    half: false,
    required: false,
    placeholder: ''
  })

  const emit = defineEmits(['update:modelValue', 'change', 'text-change'])
  const rnd = ref<number>(Number(Math.random() * 10000000))

  const toolbar = ref<any[]>([
    [{ font: [] }, { size: [] }],
    ['bold', 'italic', 'underline', 'strike'],
    [{ color: [] }, { background: [] }],
    [{ script: 'super' }, { script: 'sub' }],
    [{ header: '1' }, { header: '2' }, 'blockquote'],
    [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
    [{ align: [] }],
    ['link', 'image', 'video'],
    ['clean']
  ])

  const options = reactive<Record<string, any>>({
    theme: 'snow',
    modules: {
      toolbar: toolbar.value,
      imageResize: {
        modules: ['Resize', 'DisplaySize', 'Toolbar']
      }
    },
    placeholder: props.placeholder,
    readOnly: false,
    debug: false
  })

  const QuillImageResize = ref<any>()

  const editor = useTemplateRef<any>('quillContainer' + rnd.value)
  const quill = ref<Quill | null>(null)

  const localValue = ref<string>(props.modelValue)

  const InvalidMessageText = ref<Record<string, any>>({})
  const InvalidMessages = computed(() => {
    let text = ''
    Object.keys(InvalidMessageText.value).forEach((k: string, i: number) => {
      text += InvalidMessageText.value[k] + ', '
    })
    return text
  })

  const OnTextChange = (e: any) => {
    if (props.minlength !== undefined) {
      if (localValue.value.length < Number(props.minlength)) {
        InvalidMessageText.value.minlength = `Girdiğiniz bilgi en az ${props.minlength} karakter uzunluğunda olmalı`
      } else {
        delete InvalidMessageText.value.minlength
      }
    }

    if (quill.value !== null) {
      localValue.value = quill.value!.container.querySelector('.ql-editor')!.innerHTML
    }

    emit('update:modelValue', localValue.value)
    emit('change', e)
  }

  const InitializeEditor = async () => {
    await setupQuillEditor()
    SetContent()
    RegisterEditorEventListeners()
  }

  const SetContent = () => {
    if (props.modelValue) quill.value!.root.innerHTML = props.modelValue
  }

  const setupQuillEditor = async () => {
    //let Parchment = Quill.import('parchment')

    window.Quill.imports.parchment.Attributor.Style =
      window.Quill.imports.parchment.StyleAttributor

    //@ts-ignore
    QuillImageResize.value = await import('quill-image-resize-module')

    quill.value = new Quill(editor.value, options) as Quill
    ;(quill.value!.getModule('toolbar') as Record<
      string,
      any
    >)!.container.addEventListener('mousedown', (e: Event) => {
      e.preventDefault()
    })
    ;(quill.value!.getModule('toolbar') as Record<
      string,
      any
    >)!.container.addEventListener('click', (e: Event) => {
      if ((e.target as HTMLElement).className !== 'ql-image') e.preventDefault()
    })
  }

  const RegisterEditorEventListeners = () => {
    quill.value!.on('text-change', OnTextChange)
    quill.value!.on('editor-change', OnTextChange)
    //image resize imaja tıklandığını anlamıyor.
    quill.value!.root.addEventListener('mouseover', OnMouseOver, false)
    ListenForEditorEvent('text-change')
  }
  const ListenForEditorEvent = (type: any) => {
    quill.value!.on(type, (...args) => {
      emit(type, ...args)
    })
  }

  const OnMouseOver = (e: Event) => {
    if (
      (e.target as HTMLElement)!.firstChild &&
      ((e.target as HTMLElement)!.firstChild as HTMLElement)!.tagName &&
      ((e.target as HTMLElement)!.firstChild as HTMLElement)!.tagName.toUpperCase() ===
        'IMG'
    ) {
      ;(e.target as HTMLElement)!.classList.add('remove-click-p')
      ;((e.target as HTMLElement)!.firstChild as HTMLElement)!.classList.add(
        'add-click-img'
      )
    }
  }

  onMounted(async () => {
    InitializeEditor()
  })

  watch(
    () => props.invalidText,
    () => {
      if (props.invalidText !== undefined && props.invalidText !== '') {
        InvalidMessageText.value.invalid = props.invalidText
      } else {
        delete InvalidMessageText.value.invalid
      }
    }
  )
</script>
<style>
  .ql-toolbar {
    width: 100%;
  }
  .ql-container {
    width: 100%;
    min-height: 120px;
  }
  .remove-click-p {
    pointer-events: none;
  }
  .add-click-img {
    pointer-events: all;
  }
</style>
