<script setup>
import { onMounted, onUnmounted, ref, createApp } from 'vue';
import ToastManager from '~/components/managers/ToastManager.vue';
import { emitter } from '~/services/Emitter';
import { GetWidget, ParseMarkdown } from '~/services/Marker';
import Server from '~/services/Server';
import { DisplayToast } from '~/services/Toaster';
import TestWidget from '../widgets/TestWidget.vue';

// import { GetNote, GetContent } from '@/services/Content';
const props = defineProps(['text', 'title', 'noteKey']);
const noteContent = ref(null); // Markdown text

const sourceText = ref(''); // Original markdown source, used for editing
const displayText = ref(''); // Compiled HTML from markdown

const editingMode = ref(false);
const title = ref(props.title);
const isDirty = ref(false);
const showClose = ref(false);

let savedState = { text: '', title: '' };

function markDirty() {
    isDirty.value = sourceText.value !== savedState.text || title.value !== savedState.title;
}

function closeNote(){
    emitter.emit('delete-note', props.noteKey);
}

const compiledMarkdown = computed(() => {
    return ParseMarkdown(sourceText.value);
});

function mountComponents() {
  // Should no need more
  const widget_types = ['display', 'inline'];
  widget_types.forEach((widget_type) => {
    const nodes = document.querySelectorAll('.vue-component-' + widget_type);
    nodes.forEach(el => {
      const app = createApp(GetWidget(widget_type, el.dataset.component), { content: el.dataset.content });
      app.mount(el);
    });
  });
}
/// 

function update(){
    displayText.value = compiledMarkdown.value;
    setTimeout(() => {
      setupCallout()
      mountComponents();
    }, 0);
}

watch(sourceText, markDirty);

watch(title, markDirty);

onMounted(() => {
    sourceText.value = props.text;
    title.value = props.title;
  
    savedState = { text: props.text, title: props.title };
    emitter.on('title-updated', handleTitleUpdate);
    // window.addEventListener('keydown', handleKeydown);
    setTimeout(() => setupCallout(), 0);
    update();
});

function handleTitleUpdate(data) {
    if (data.key !== props.noteKey) return;
    title.value = data.title;
    savedState.title = data.title;
}

onUnmounted(() => {
  emitter.off('title-updated', handleTitleUpdate);
  // window.removeEventListener('keydown', handleKeydown);
});

function handleKeydown(e) {
  // Check for Ctrl + E (or Cmd + E on Mac)
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'e') {
    e.preventDefault(); // prevent browser default behavior
    editingMode.value = !editingMode.value;
    if(!editingMode.value){
       update();
       SaveNote(); // Save when switching to display mode
    }
    return;
  }

  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') {
    e.preventDefault(); // prevent browser default behavior
    // Save the note (you can emit an event or call a method here)
    SaveNote();
    return;
  }
}

function SaveNote(){
    Server().post('/note/update', {
        id: props.noteKey,
        content: sourceText.value,
        title: title.value,
    }).then((response) => {
        if(response.data.status !== 'ok'){
            return;
        }
        savedState = { text: sourceText.value, title: title.value };
        isDirty.value = false;
    }).catch((error) => {
    });
}

function toggleCallout() {
  const outerBlock = this.parentElement;
  outerBlock.classList.toggle("is-collapsed")
  const collapsed = outerBlock.classList.contains("is-collapsed")
  const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight
  outerBlock.style.maxHeight = height + "px"

  // walk and adjust height of all parents
  let current = outerBlock
  let parent = outerBlock.parentElement
  while (parent) {
    if (!parent.classList.contains("callout")) {
      return
    }

    const collapsed = parent.classList.contains("is-collapsed")
    const height = collapsed ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight
    parent.style.maxHeight = height + "px"

    current = parent
    parent = parent.parentElement
  }
}

function setupCallout() {
  if (!noteContent.value) {
    return;
  }

  const collapsible = noteContent.value.getElementsByClassName(
    `callout is-collapsible`,
  );
  for (const div of collapsible) {
    const title = div.firstElementChild;

    if (title) {
      title.addEventListener("click", toggleCallout)

      const collapsed = div.classList.contains("is-collapsed")
      const height = collapsed ? title.scrollHeight : div.scrollHeight
      div.style.maxHeight = height + "px"
    }
  }
}


</script>

<template>
<div class="note" @keydown="handleKeydown" tabindex="0">
    <div class="note-stunt">
        <div class="unsaved-wrapper" v-if="isDirty">
            <div class="unsaved-dot"></div>
            <div class="close-button close-hidden" v-on:click="closeNote">
                <img class="icon" src="/icons/Pixelarticons/white/close.svg" alt="My Happy SVG"/>
            </div>
        </div>
        <div class="close-button" v-else v-on:click="closeNote">
            <img class="icon" src="/icons/Pixelarticons/white/close.svg" alt="My Happy SVG"/>
        </div>
        <span>{{ title }}</span>
    </div>
    <div class="note-content-container">
        <textarea v-model="sourceText" class="full-editor" v-if="editingMode"></textarea>
        <div v-else class="note-content" ref="noteContent">
          <h1>{{ title }}</h1>
          <div ref="noteContent" v-html="displayText"></div>
        </div>
        
    </div>
</div>
</template>

<style scoped>
.note-stunt {
    writing-mode: vertical-lr;
    position: sticky;
    top: 0px;
    left: 0px;
    bottom: 0px;
    padding: 10px;
    display: flex;
    user-select: none;
}

.unsaved-wrapper {
    position: relative;
    margin-bottom: 5px;
    width: 20px;
    height: 20px;
}

.unsaved-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: #ffffff;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.close-hidden {
    opacity: 0;
    visibility: hidden;
    position: absolute;
    top: 0;
    left: 0;
    width: 20px;
    height: 20px;
    margin-bottom: 0;
    transition: opacity 0.15s ease, visibility 0.15s ease;
}

.unsaved-wrapper:hover .close-hidden {
    opacity: 1;
    visibility: visible;
}

.unsaved-wrapper:hover .unsaved-dot {
    opacity: 0;
}

.full-editor {
width: 100%;    
  height: 100%;
  box-sizing: border-box;

  border: none;
  outline: none;
  resize: none;

  padding: 20px;
  font-size: 16px;
  font-family: monospace; /* optional, gives document/editor feel */

    padding-bottom: 400px; /* Small bottom margin */
}

.close-button {
    height: 20px;
    width: 20px;
    margin-bottom: 5px;
    display: flex;
    justify-content: center;
    cursor: pointer;
    filter: invert(var(--color-icon-invert));
}

.note {
    min-width: 700px;
    max-width: 700px;
    overflow-y: auto;

    border-color: var(--color-note-border);
    border-width: 0px;
    border-right-width: 1px;
    border-style: solid;
    display: flex;

    background-color: var(--color-background);
    position: sticky;
    top: 0px;
}

/* Contingut de cada nota */
.note-content {
    padding-bottom: 400px;
    overflow-y: auto;
    max-width: 600px;
    padding: 20px;
}

.note-content-container {
    width: 100%;
}

.note-content :deep(img) {
  max-width: 100%;
  height: auto;
  display: block; /* optional: avoids inline spacing issues */
}
</style>
