<template>
  <div class="edit-pages">
    <h2>Webseiten bearbeiten</h2>
    <div>
      <label for="page-select">Wähle eine Seite:</label>
      <select id="page-select" v-model="selectedPage" @change="loadPageContent">
        <option v-for="page in sortedPages" :key="page.link" :value="page.link">{{ page.name }}</option>
      </select>
    </div>
    <div class="toolbar">
      <button @click="toggleHeading(3)" :class="{ 'is-active': editor && editor.isActive('heading', { level: 3 }) }">H3</button>
      <button @click="toggleHeading(4)" :class="{ 'is-active': editor && editor.isActive('heading', { level: 4 }) }">H4</button>
      <button @click="toggleHeading(5)" :class="{ 'is-active': editor && editor.isActive('heading', { level: 5 }) }">H5</button>
      <button @click="toggleHeading(6)" :class="{ 'is-active': editor && editor.isActive('heading', { level: 6 }) }">H6</button>
      <button @click="toggleBold()" :class="{ 'is-active': editor && editor.isActive('bold') }" width="24" height="24">
        <BoldIcon width="24" height="24" />
      </button>
      <button @click="toggleItalic()" :class="{ 'is-active': editor && editor.isActive('italic') }">
        <ItalicIcon width="24" height="24" />
      </button>
      <button @click="toggleUnderline()" :class="{ 'is-active': editor && editor.isActive('underline') }">
        <UnderlineIcon width="24" height="24" />
      </button>
      <button @click="toggleStrike()" :class="{ 'is-active': editor && editor.isActive('strike') }">
        <StrikethroughIcon width="24" height="24" />
      </button>
      <button @click="insertTable()">
        <TableIcon width="24" height="24" />
      </button>
      <button @click="toggleBulletList()" :class="{ 'is-active': editor && editor.isActive('bulletList') }">
        <ListIcon width="24" height="24" />
      </button>
      <button @click="toggleOrderedList()" :class="{ 'is-active': editor && editor.isActive('orderedList') }">
        <NumberedListLeftIcon width="24" height="24" />
      </button>
      <button @click="openAddImageDialog">
        <StatsReportIcon width="24" height="24" />
      </button>
      <button @click="openAddLinkDialog">
        <OpenInWindowIcon width="24" height="24" />
      </button>
      <button @click="openAddDownloadDialog">
        <DownloadIcon width="24" height="24" />
      </button>
      <button @click="openColorPicker">Schriftfarbe</button>
      <input type="color" ref="colorPicker" @input="setColor" style="display: none;" />
    </div>
    <div class="table-toolbar">
      <button @click="addColumnBefore()">
        <ArrowDownIcon width="10" height="10" class="align-top" />
        <Table2ColumnsIcon width="24" height="24" />
      </button>
      <button @click="addColumnAfter()">
        <Table2ColumnsIcon width="24" height="24" />
        <ArrowDownIcon width="10" height="10" class="align-top" />
      </button>
      <button @click="addRowBefore()">
        <ArrowRightIcon width="10" height="10" class="align-top" />
        <TableRowsIcon width="24" height="24" />
      </button>
      <button @click="addRowAfter()">
        <ArrowRightIcon width="10" height="10" />
        <TableRowsIcon width="24" height="24" />
      </button>
      <button @click="deleteColumn()">
        <Table2ColumnsIcon width="24" height="24" class="delete-icon" />
      </button>
      <button @click="deleteRow()">
        <TableRowsIcon width="24" height="24" class="delete-icon" />
      </button>
      <button @click="toggleHeaderColumn()">
        <AlignTopBoxIcon width="24" height="24" />
      </button>
      <button @click="toggleHeaderRow()">
        <AlignLeftBoxIcon width="24" height="24" />
      </button>
    </div>
    <div class="additional-toolbar">
      <button @click="openAddEventsDialog">Events</button>
      <button @click="openAddContactDialog">Kontaktpersonen</button>
      <button @click="openAddInstitutionDialog">Institutionen</button>
      <button @click="openWorshipDialog">Gottesdienste</button>
    </div>
    <div :class="['htmleditor']">
      <EditorContent :editor="editor" />
    </div>
    <button @click="savePageContent">Speichern</button>

    <WorshipDialog ref="worshipDialog" @confirm="insertWorshipList" />
    <AddImageDialog ref="addImageDialog" @confirm="insertImage" />
    <AddContactDialog ref="addContactDialog" @confirm="insertContact" />
    <AddEventDialog ref="addEventDialog" @confirm="insertEvent" />
    <AddLinkDialog ref="addLinkDialog" @confirm="insertLink" />
    <AddDownloadDialog ref="addDownloadDialog" @confirm="insertDownload" />
    <AddInstitutionDialog ref="addInstitutionDialog" @confirm="insertInstitution" />
    <input type="color" ref="colorPicker" @input="setColor" style="display: none;" />
  </div>
</template>

<script>
import { ref, computed, onMounted, watch } from 'vue';
import { useStore } from 'vuex';
import axios from '../../axios';
import { EditorContent, useEditor } from '@tiptap/vue-3';
import StarterKit from '@tiptap/starter-kit';
import { Table } from '@tiptap/extension-table';
import { TableRow } from '@tiptap/extension-table';
import { Bold } from '@tiptap/extension-bold';
import { Italic } from '@tiptap/extension-italic';
import { Underline } from '@tiptap/extension-underline';
import { Strike } from '@tiptap/extension-strike';
import { BulletList } from '@tiptap/extension-bullet-list';
import { OrderedList } from '@tiptap/extension-ordered-list';
import { Heading } from '@tiptap/extension-heading';
import { Link } from '@tiptap/extension-link';
import { TextStyle } from '@tiptap/extension-text-style';
import { Color } from '@tiptap/extension-color';
import { CustomTableCell, CustomTableHeader } from '../../extensions/CustomTableCell';
import WorshipDialog from '@/components/WorshipDialog.vue';
import AddImageDialog from '@/components/AddImageDialog.vue';
import AddContactDialog from '@/components/AddContactDialog.vue';
import AddEventDialog from '@/components/AddEventDialog.vue';
import AddLinkDialog from '@/components/AddLinkDialog.vue';
import AddDownloadDialog from '@/components/AddDownloadDialog.vue';
import AddInstitutionDialog from '@/components/AddInstitutionDialog.vue';
import { BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, ListIcon, NumberedListLeftIcon, TableIcon,
  Table2ColumnsIcon, ArrowDownIcon, ArrowRightIcon, TableRowsIcon, AlignTopBoxIcon, AlignLeftBoxIcon, StatsReportIcon,
  OpenInWindowIcon, DownloadIcon
 } from '@/icons';

export default {
  name: 'EditPagesComponent',
  components: {
    EditorContent,
    WorshipDialog,
    AddImageDialog,
    BoldIcon,
    ItalicIcon,
    UnderlineIcon,
    StrikethroughIcon, 
    ListIcon,
    NumberedListLeftIcon,
    TableIcon,
    Table2ColumnsIcon,
    ArrowDownIcon,
    ArrowRightIcon,
    TableRowsIcon,
    AlignTopBoxIcon,
    AlignLeftBoxIcon,
    StatsReportIcon,
    AddEventDialog,
    AddContactDialog,
    AddLinkDialog,
    AddDownloadDialog,
    AddInstitutionDialog,
    OpenInWindowIcon,
    DownloadIcon,
  },
  setup() {
    const store = useStore();
    const pages = ref([]);
    const selectedPage = ref('');
    const pageHtmlContent = computed(() => store.state.pageContent);
    const worshipDialog = ref(null);
    const addImageDialog = ref(null);
    const addEventDialog = ref(null);
    const addContactDialog = ref(null);
    const addLinkDialog = ref(null);
    const addDownloadDialog = ref(null);
    const addInstitutionDialog = ref(null);
    const colorPicker = ref(null);

    const editor = useEditor({
      extensions: [
        StarterKit,
        Table.configure({
          resizable: true,
        }),
        TableRow,
        CustomTableCell,
        CustomTableHeader,
        Bold,
        Italic,
        Underline,
        Strike,
        BulletList,
        OrderedList,
        Heading.configure({
          levels: [3, 4, 5, 6],
        }),
        Link.configure({
          openOnClick: false,
        }),
        TextStyle,
        Color,
      ],
      content: '',
      onUpdate: ({ editor }) => {
        store.commit('SET_PAGE_CONTENT', editor.getHTML());
      },
    });

    const flattenPages = (pages, allPages, parentName = '') => {
      pages.forEach(page => {
        const pageName = parentName ? `${parentName} -> ${page.name}` : page.name;
        allPages.push({ ...page, name: pageName });
        if (page.submenu && page.submenu.length) {
          flattenPages(page.submenu, allPages, pageName);
        }
      });
    };

    const fetchPages = async () => {
      try {
        const response = await axios.get('/menu-data');
        const data = response.data;
        const allPages = [];
        flattenPages(data, allPages);
        pages.value = allPages.sort((a, b) => a.name.localeCompare(b.name));
        store.commit('setMenuData', data);
      } catch (error) {
        console.error('Fehler beim Abrufen der Seiten:', error);
      }
    };

    const loadPageContent = async () => {
      try {
        await store.dispatch('loadPageContent', selectedPage.value);
        const content = store.getters.pageContent;
        const setEditorContent = () => {
          if (editor.value && editor.value.commands) {
            editor.value.commands.setContent(content, false);
          } else {
            setTimeout(setEditorContent, 100);
          }
        };
        setEditorContent();
      } catch (error) {
        console.error('Fehler beim Laden des Seiteninhalts:', error);
      }
    };

    const savePageContent = async () => {
      try {
        const selectedPageName = pages.value.find(page => page.link === selectedPage.value)?.name || '';
        if (!selectedPageName) {
          return;
        }

        const contentToSave = editor.value.getHTML();
        store.commit('SET_PAGE_CONTENT', contentToSave);

        await store.dispatch('savePageContent', {
          link: selectedPage.value,
          name: selectedPageName,
        });
      } catch (error) {
        console.error('Fehler beim Speichern des Seiteninhalts:', error);
      }
    };

    onMounted(fetchPages);

    const sortedPages = computed(() => {
      return pages.value;
    });

    watch(selectedPage, (newPage) => {
      store.dispatch('setSelectedPage', newPage);
      const page = pages.value.find(page => page.link === newPage);
      if (page) {
        store.dispatch('setPageTitle', page.name);
      }
      loadPageContent();
    });

    const openWorshipDialog = () => {
      worshipDialog.value.openWorshipDialog();
    };

    const openAddImageDialog = () => {
      addImageDialog.value.openAddImageDialog();
    };

    const insertWorshipList = (selectedLocations) => {
      if (editor.value) {
        const configuration = {
          location: selectedLocations,
          order: "date asc",
        }
        editor.value.chain().focus().insertContent('{{ worshipslist:' + JSON.stringify(configuration) + ' }}').run();
      }
    };

    const insertImage = (selectedImage) => {
      if (editor.value) {
        editor.value.chain().focus().insertContent(`{{ image:${selectedImage} }}`).run();
      }
    };

    const openAddEventDialog = () => {
      addEventDialog.value.openAddEventDialog();
    };

    const insertEvent = (configString) => {
      if (editor.value) {
        editor.value.chain().focus().insertContent(configString).run();
      }
    };

    const openAddContactDialog = () => {
      addContactDialog.value.openAddContactDialog();
    };

    const insertContact = (contactPersonString) => {
      if (editor.value) {
        editor.value.chain().focus().insertContent(contactPersonString).run();
      }
    };

    const openAddLinkDialog = () => {
      addLinkDialog.value.openAddLinkDialog();
    };

    const insertLink = (url, text) => {
      if (!editor.value) return;
      if (!url) return;
      const selectionText = editor.value.state.doc.textBetween(
        editor.value.state.selection.from,
        editor.value.state.selection.to
      );
      const linkText = (text && text.trim()) || selectionText || url;
      // Einfaches Escaping für Text
      const escapeHtml = (s) => s.replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#39;'}[c]));
      const safeText = escapeHtml(linkText);
      const safeUrl = url.trim();
      // Direkter HTML Insert, damit der Link garantiert entsteht
      editor.value.chain().focus().insertContent(`<a href="${safeUrl}" target="_blank" rel="noopener noreferrer">${safeText}</a>`).run();
    };

    const openAddDownloadDialog = () => {
      addDownloadDialog.value.openAddDownloadDialog();
    };

    const insertDownload = ({ hash }) => {
      if (hash && editor.value) {
        const downloadString = '{{ download:' + hash + ' }}'
        editor.value.chain().focus().insertContent(downloadString).run();
      }
    };

    const openAddInstitutionDialog = () => {
      addInstitutionDialog.value.openAddInstitutionDialog();
    };

    const insertInstitution = (configString) => {
      if (editor.value) {
        editor.value.chain().focus().insertContent(configString).run();
      }
    };

    const openColorPicker = () => {
      colorPicker.value.click();
    };

    const setColor = (event) => {
      const color = event.target.value;
      if (editor.value) {
        editor.value.chain().focus().setColor(color).run();
      }
    };

    const toggleHeading = (level) => {
      editor.value.chain().focus().toggleHeading({level: level}).run();
    };

    const toggleItalic = () => {
      editor.value.chain().focus().toggleItalic().run();
    };

    const toggleBold = () => {
      editor.value.chain().focus().toggleBold().run();
    };

    const toggleUnderline = () => {
      editor.value.chain().focus().toggleUnderline().run();
    };

    const toggleStrike = () => {
      editor.value.chain().focus().toggleStrike().run();
    };

    const insertTable = () => {
      editor.value.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
    };

    const toggleBulletList = () => {
      editor.value.chain().focus().toggleBulletList().run();
    };

    const toggleOrderedList = () => {
      editor.value.chain().focus().toggleOrderedList().run();
    };

    return {
      pages,
      sortedPages,
      selectedPage,
      editor,
      loadPageContent,
      savePageContent,
      pageHtmlContent,
      openWorshipDialog,
      insertWorshipList,
      worshipDialog,
      addImageDialog,
      openAddImageDialog,
      insertImage,
      addEventDialog,
      openAddEventsDialog: openAddEventDialog,
      addContactDialog,
      openAddContactDialog,
      insertContact,
      insertEvent,
      addLinkDialog,
      openAddLinkDialog,
      insertLink,
      addDownloadDialog,
      openAddDownloadDialog,
      insertDownload,
      addInstitutionDialog,
      openAddInstitutionDialog,
      insertInstitution,
      colorPicker,
      openColorPicker,
      setColor,
      toggleHeading,
      toggleBold,
      toggleItalic,
      toggleUnderline,
      toggleStrike,
      insertTable,
      toggleBulletList,
      toggleOrderedList,
    };
  },
};
</script>

<style scoped>
.edit-pages {
  width: 100%;
  margin: auto;
}

#page-select {
  margin-bottom: 20px;
}

.toolbar {
  margin-bottom: 10px;
}

.toolbar button {
  margin-right: 5px;
}

.table-toolbar {
  margin-bottom: 10px;
}

.table-toolbar button {
  margin-right: 5px;
}

.additional-toolbar {
  margin-bottom: 10px;
}

.additional-toolbar button {
  margin-right: 5px;
}

.ql-container {
  background-color: #fff !important;
}

.ql-editor {
  background-color: #fff !important;
}

.edit-pages div>button {
  border: none;
  padding: 0.25em;
  margin: 2px;
}

.button-icon {
  background-image: url(@/assets/icons/Bold_Italic_Underline.png);
  background-position: left top;
  background-size: 10px 24px;
  background-repeat: no-repeat;
  width: 24px;
  height: 24px;
}

.delete-icon {
  fill: #ff0000;
}

.align-top {
  vertical-align: top;
}

.toolbar button.is-active,
.table-toolbar button.is-active {
  background-color: #333;
  color: white;
}

.toolbar button.is-active svg,
.table-toolbar button.is-active svg {
  fill: white;
}
</style>
