<template>
  <div>
    <textarea :id="editorId" :value="modelValue" hidden></textarea>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, onBeforeUnmount, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import 'tinymce/themes/modern/theme';
import 'tinymce/plugins/code';
import 'tinymce/plugins/table';
import 'tinymce/plugins/fullscreen';
import 'tinymce/plugins/lists';
import 'tinymce/plugins/link';
import 'tinymce/plugins/textcolor';
import 'tinymce/plugins/image';

export default defineComponent({
  name: 'Editor',
  props: {
    modelValue: {
      type: String,
      required: true,
    },
    id: {
      type: String,
      default: '',
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const { t } = useI18n();
    const pluginUrl = window.loyalty_suite_admin_data.pluginUrl;
    const apiRoutes = window.loyalty_suite_admin_data.apiRoutes;
    const nonce = window.loyalty_suite_admin_data.nonce;
    const lang = window.loyalty_suite_admin_data.locale || 'en';
    const useCustomLang = lang !== 'en';
    const editorId = props.id || 'tinymce-editor-' + Math.random().toString(36).slice(2);
    let editorInstance: any = null;

    onMounted(() => {
      let attempts = 0;
      const maxAttempts = 10;

      const checkTinymce = () => {
        const tinymce = window.tinymce;

        if (tinymce) {
          tinymce.init({
            selector: `#${editorId}`,
            theme: 'modern',
            skin_url: pluginUrl + 'includes/Admin/assets/css/editor/lightgray',
            language: useCustomLang ? lang : undefined,
            language_url: useCustomLang
              ? pluginUrl + 'includes/Admin/assets/js/editor/langs/' + lang + '.js'
              : undefined,
            directionality: lang === 'ar' ? 'rtl' : 'ltr',
            menubar: false,
            branding: false,
            statusbar: false,
            relative_urls: false,
            remove_script_host: false,
            document_base_url: window.location.origin + '/',
            height: 350,
            plugins: [
              'code',
              'table',
              'fullscreen',
              'lists',
              'link',
              'textcolor',
              'image',
            ],
            toolbar:
              'undo redo removeformat | formatselect | ' +
              'bold italic underline strikethrough forecolor backcolor | link | ' +
              'alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | ' +
              'table code | customImageUpload fullscreen',
            extended_valid_elements: '',
            invalid_elements: 'script,iframe',
            content_style: 'body { font-family:Roboto,sans-serif; font-size:14px }',
            setup(editor) {
              editor.addButton('customImageUpload', {
                icon: 'image',
                tooltip: t('editor.insertImage'),
                onclick: function () {
                  const input = document.createElement('input');
                  input.type = 'file';
                  input.accept = 'image/*';

                  input.onchange = function () {
                    const file = input.files?.[0];
                    if (!file) return;

                    const formData = new FormData();
                    formData.append('image', file, file.name);

                    fetch(apiRoutes.admin.image_save, {
                      method: 'POST',
                      headers: {
                        'X-WP-Nonce': nonce,
                      },
                      body: formData,
                    })
                      .then((res) => res.json())
                      .then((json) => {
                        if (json && json.url) {
                          editor.insertContent(`<img src="${json.url}" title="${file.name}" />`);
                        } else {
                          alert('Upload failed');
                        }
                      })
                      .catch(() => {
                        alert('Upload failed');
                      });
                  };

                  input.click();
                },
              });

              editor.on('init', () => {
                editor.setContent(props.modelValue || '');
              });
              editor.on('change keyup', () => {
                emit('update:modelValue', editor.getContent());
              });

              editorInstance = editor;
            },
          });
        } else if (attempts < maxAttempts) {
          attempts++;
          setTimeout(checkTinymce, 100);
        } else {
          console.error('TinyMCE failed to load after multiple attempts');
        }
      };

      checkTinymce();
    });

    onBeforeUnmount(() => {
      const tinymce = window.tinymce;
      if (editorInstance) {
        tinymce.remove(editorInstance);
      }
    });

    watch(
      () => props.modelValue,
      (val) => {
        if (editorInstance && val !== editorInstance.getContent()) {
          editorInstance.setContent(val || '');
        }
      }
    );

    return {
      editorId,
    };
  },
});
</script>
