<template>
  <div class="lofty-disclaimer" ref="root">
   <div class="disclaimer-title">
     <label>DISCLAIMER</label>
     <span class="insert-variable" @click="openPop">
         <span class="plus-icon">+</span>
         <span>Add hyperlink</span>
       </span>
   </div>

   <div class="disclaimer-content"
        ref="editorRich"
        placeholder="By checking this box, I confirm that I have read and agree to the Terms of Service, Privacy Policy, and E-Signature Disclosure."
        contenteditable
        @keyup="inputFilter"
        @keydown="inputFilter"
        @paste="pasteValue"
        @click.stop="clickEditor"></div>

    <pop ref="popRef" :allowClose="false">
      <div class="pop-disclaimer-container">
        <div class="title">
          Add Hyperlink
          <i class="lofty_iconfont lofty-icon-close" @click="close"></i>
        </div>
        <div class="disclaimer-pop-body">
          <label>HYPERLINK TEXT</label>
          <input v-model="form.name" type="text">
          <label>URL</label>
          <input v-model="form.url" type="text">
        </div>
        <div class="disclaimer-footer">
          <div class="footer-cancel" @click="close">Cancel</div>
          <div class="footer-save" @click="confirm">Save</div>
        </div>
      </div>
    </pop>
  </div>
</template>

<script setup>
import { throttle } from '@/util/index.js';
import Pop from '@/components/pop/index.vue';
const editorRich = useTemplateRef('editorRich');
const popRef = useTemplateRef('popRef');
const rootRef = useTemplateRef('root');
const model = defineModel()
const form = reactive({
  name: '',
  url: ''
})
function close() {
  popRef.value.close()
}
function confirm() {
  if(form.name && form) {
    insertVariable()
    popRef.value.close()
  }
}
function openPop() {
  form.name = ''
  form.url = ''
  popRef.value.open();
}

let lastRange = null;
function insertVariable() {
  nextTick(() => {
    let editorEl = editorRich.value;
    if (!lastRange) {
      collapseToEnd();
    }
    let tagEl = document.createElement('a');
    tagEl.className = 'lofty-a-link';
    tagEl.setAttribute('contenteditable', 'false');
    tagEl.setAttribute('href', form.url);
    tagEl.setAttribute('target', '_blank');
    tagEl.setAttribute('rel', 'noopener noreferrer');
    tagEl.innerHTML = `${form.name}`;
    if (!lastRange) {
      return;
    }
    lastRange.insertNode(tagEl);
    let currentSelection = window.getSelection();
    currentSelection.collapseToEnd();
    currentSelection.removeAllRanges();
    editorEl.blur();
    changeInputValue();
  })
}
function clickEditor(ev) {
  let currentSelection = window.getSelection();
  if (currentSelection.rangeCount <= 0) {
    return;
  }
  let currentRange = currentSelection.getRangeAt(0);
  let targetEl = ev.target
  let classList = targetEl.classList || null;
  if (classList && classList.contains('lofty-a-link')) {
    //disabled inserted variable to tag inside
    currentRange.selectNode(targetEl);
    currentRange.collapse(false);
    currentSelection.removeAllRanges();
    currentSelection.addRange(currentRange);
  }
  changeInputValue();
}
function collapseToEnd() {
  let currentRange = document.createRange();
  let currentSelection = window.getSelection();
  currentRange.selectNodeContents(editorRich.value);
  currentRange.collapse(false);
  currentSelection.removeAllRanges();
  currentSelection.addRange(currentRange);
  lastRange = saveSelection();
}
function saveSelection() {
  const sel = document.getSelection();
  if (sel.rangeCount <= 0) {
    return null;
  }
  return sel.getRangeAt(0);
}
function inputFilter(ev) {
  if(model.value.length > 2000 && ev.key !== 'Backspace' && ev.key !== 'Delete') {
    ev.preventDefault();
    return;
  }
  throttle(() => {
    if (ev.type === 'keyup') {
      changeInputValue();
    }
  })();
}
function pasteValue(e) {
  if(lastRange && e.clipboardData) {
    let pasteData = e.clipboardData.getData('text/plain');
    let textNode = document.createTextNode(pasteData.slice(0, 2000));
    let pasteRange = lastRange;
    let pasteSelection = window.getSelection();
    pasteSelection.deleteFromDocument();
    pasteRange.insertNode(textNode);
    pasteRange.setStartAfter(textNode);
    pasteRange.setEndAfter(textNode);
    pasteRange.collapse(false);
    pasteSelection.removeAllRanges();
    pasteSelection.addRange(pasteRange);
    e.preventDefault();
    changeInputValue();
  }
}
function changeInputValue() {
  lastRange = saveSelection();
  if (editorRich.value) {
    model.value = editorRich.value.innerHTML.replace("<br>", "");
  }
}
function getValueString() {
  const textarea = document.createElement('textarea');
  textarea.innerHTML = editorRich.value.innerHTML;
  let result = textarea.value
  result = result.replace(/<(?!a\b|\/a\b|br\b)[^>]*>/gi, '');
  result = result.replace(/<br\s*\/?>/gi, '');
  return result
}

onMounted(()=>{
  editorRich.value.style.width = rootRef.value.clientWidth + 'px';
})
defineExpose({
  getValueString
})

watch(() => model.value, (html) => {
  editorRich.value.innerHTML = html;
}, {
  once: true
})
</script>
<style scoped lang="scss">
.disclaimer-title {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  label {
    font-size: 11px;
    color: $gray-800;
    font-weight: 500;
  }
  .insert-variable {
    margin-left: auto;
    color: $color-theme;
    cursor: pointer;
    .plus-icon {
      position: relative;
      top: 2px;
      font-size: 1.2rem;
      margin-right: 5px;
    }
  }
}
.disclaimer-content {
  min-height: 160px;
  max-width: 100%;
  height: auto;
  color: #000;
  background-color: #fff;
  border: 1px solid #949494;
  border-radius: 2px;
  padding: 12px;
  &:hover {
    border-color: $color-theme;
  }
  &:empty::before {
    content: attr(placeholder);
    color: #C6C8D1;
    font-size: 14px;
    cursor: text;
  }
}
</style>
<style lang="scss">
.lofty-a-link {
  color: rgba(56, 88, 233, 1);
  text-decoration: underline;
}
.pop-disclaimer-container {
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 8px;
  .title {
    display: flex;
    font-size: 18px;
    color: $gray-900;
  }
  .disclaimer-pop-body {
    width: 450px;
    margin-top: 20px;
    label {
      display: block;
      font-size: 11px;
      color: $gray-800;
      margin-bottom: 8px;
    }
    input + label {
      margin-top: 20px;
    }
  }
  .disclaimer-footer {
    display: flex;
    align-items: center;
    padding-top: 20px;
    height: 40px;
    > div {
      cursor: pointer;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .footer-cancel {
      margin-left: auto;
      margin-right: 10px;
    }
    .footer-save {
      background-color: $color-theme;
      border-radius: $radius-small;
      color: #fff;
      width: 60px;
    }
  }
}
</style>