<template>
  <div style="width: 100%; height: 100%; position: relative; overflow: hidden">
    <iframe
      :src="src"
      width="100%"
      scrolling="no"
      height="100%"
      style="position: relative; border: medium none;"
      ref="iframeRef"
      @load="onLoad"
    >
    </iframe>
    <div class="close-icon" @click="emits('close')" v-if="false">
      <CloseOutlined />
    </div>
  </div>
</template>
<script setup>
import { CloseOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { nextTick } from 'vue';
const iframeRef = ref(null);
const emits = defineEmits(['close', 'outline', 'search', 'load']);
const searchList = ref([]);
const pageContent = ref([]);
const pageText = ref([]);
const props = defineProps({
  src: String
});
const type = ref('pdf');

watch(
  () => props.src,
  (v) => {
    if (v.endsWith('.pdf')) {
      type.value = 'pdf';
    } else if (v.endsWith('.txt')) {
      type.value = 'txt';
    }
  },
  { immediate: true }
);

const onLoad = () => {
  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
  //待定
  // var toolbar = doc.getElementsByClassName('toolbar');
  // if (toolbar && toolbar.length > 0) {
  // toolbar[0].style.display = 'none';
  // }
  setTimeout(() => {
    const script = doc.createElement('script');
    script.textContent = `
  window.addEventListener('message', (event) => {
  const message = event.data;
  if (message.action === 'locateElement') {
    const element= document.getElementById('hightlight-'+message.index);
    debugger;
    if(element!=null&&element.offsetParent){
    setTimeout(() => {
        element.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }, 10);
    }
  }
  if (message.action === 'mlLocateElement') {

    const elements= document.getElementsByClassName(message.className);
    if(elements!=null){
     setTimeout(() => {
        elements[message.index].scrollIntoView({ behavior: 'smooth', block: 'center' })
      }, 50);
    }
  }
  });`;
    doc.body.appendChild(script);
    const style = doc.createElement('style');
    style.textContent = `
  #outerContainer{
   overflow: hidden;
  }
   #page-container{
  overflow: hidden;
   }
   #viewerContainer{
     overflow: hidden;
   }
  .canvasWrapper {
  position: relative;
  /* display: flex;
  justify-content: center; */
}

.textLayer {
  text-align: initial;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  opacity: 1;
  line-height: 1;
  text-size-adjust: none;
  forced-color-adjust: none;
}
.textLayer span,
.textLayer br {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
.highlight-layer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  opacity: 0.15;
  overflow: hidden;
}
.flash {
  animation: flashing 0.6s;
  animation-iteration-count: 2;
}
@keyframes flashing {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.15;
  }
}
.highlight {
  background-color: #0076fa;
  position: absolute;
}
  `;
    doc.head.appendChild(style);
  }, 400);
  setTimeout(() => {
    var el = doc.getElementsByClassName('page');
    // var singleHeight = 1263;
       var singleHeight = 1000;
    if (iframeRef.value.height != singleHeight * el.length) {
      iframeRef.value.height = singleHeight * el.length;
    }
    setTimeout(() => {
      pageText.value = [];
      pageContent.value = [];
      //获取每页数据
      var textDivs = doc.getElementsByClassName('textLayer');
      if (textDivs) {
        for (var i = 0; i < textDivs.length; i++) {
          var item = { page: i + 1, txt: textDivs[i].innerText };
          var items = [];
          for (var j = 0; j < textDivs[i].children.length; j++) {
            var citem = {
              str: textDivs[i].children[j].innerText,
              width: textDivs[i].children[j].getBoundingClientRect().width,
              top: textDivs[i].children[j].getBoundingClientRect().top,
              height: textDivs[i].children[j].getBoundingClientRect().height
            };
            items.push(citem);
          }
          pageContent.value.push({ page: i + 1, items: items });
          pageText.value.push(item);
        }
      }
    }, 1000);
  }, 1000);
};
const src = computed(() => {
  // return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();
  return `/aisearch/lib/pdfjs/web/viewer.html?file=${props.src}`;
  // return `/aisearch/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();

  // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
});
const scrollTo = (item) => {
  nextTick(() => {
    setTimeout(() => {
      if (item.top) {
        locateElement(item.cs, item.index, 1);
      } else {
        //搜索
        locateElement(item.cs, item.index);
        //改变选中颜色 其他黄色
        searchList.value.forEach((citem, cindex) => {
          const iframeDocument =
            iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
          const highlightedSpan = iframeDocument.getElementById('hightlight-' + cindex);
          if (cindex == item.index) {
            highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
              'lightblue',
              'yellow'
            );
          } else {
            highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
              'yellow',
              'lightblue'
            );
          }
        });
      }
    }, 10);
  });
};
const locateElement = (className, index, type) => {
  const message = {
    action: type ? 'mlLocateElement' : 'locateElement',
    className: className,
    index: index
  };
  iframeRef.value.contentWindow.postMessage(message, '*');
};
const gotoElement = (element) => {
  nextTick(() => {
    element.scrollIntoView({ behavior: 'smooth', block: 'center' });
  });
};
const highlightText = (str) => {
  setTimeout(() => {
    removeHighlight();
    heightSingle(str);
  }, 100);
};
const goLocation = (txt, flag) => {
  removeHighlight();
  searchList.value = [];
  heightSingle(txt, flag);
};
//ai 问答
const goSourceLocation = (content, type) => {
  //获取页面
  removeSourceHightLight();
  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;

  var pageNumber = 0;
  if (content.indexOf('-') > -1 && content.indexOf('-') < 3) {
    content = content.substring(content.indexOf('-') + 1);
  }
  var text = content;
  var ptText = text.replaceAll('\n', '');
  ptText = ptText.replaceAll(' ', '');
  console.log(ptText);
  pageText.value.forEach((item) => {
    item.txt = item.txt.replaceAll('\n', '');
    item.txt = item.txt.replaceAll(' ', '');
    console.log('==页=' + item.txt);
    console.log('==t=' + ptText);
    if (ptText.length > 30) {
      if (item.txt.indexOf(ptText.substring(30, 48)) > -1) {
        pageNumber = item.page;
      }
    } else {
      if (item.txt.indexOf(ptText.substring(0, 18)) > -1) {
        pageNumber = item.page;
      }
    }
  });
  text = text.replaceAll('\n', '');
  text = text.replaceAll(' ', '');
  if (text.endsWith('。') || text.endsWith('，') || text.endsWith('、')) {
    text = text.substring(0, text.length - 1);
  }
  if (pageNumber == 0) {
    message.info('未匹配到相关内容！');
    return;
  }
  //'left: 133.17px; top: 152.408px; font-size: 31.3597px; font-family: sans-serif; transform: scaleX(1.01878);'
  var arr = doc.getElementsByClassName('textLayer')[pageNumber - 1].getElementsByTagName('span');
  if (arr) {
    var hightList = [];
    var startIndex = 0;
    var endIndex = 0;
    var thirdIndex = 0;
    startIndex = getStartIndex(arr, text, text.length);
    endIndex = getEndIndex(arr, text, text.length, startIndex);
    if (startIndex && endIndex && endIndex < startIndex) {
      endIndex = startIndex + text.length;
    }
    var currentPageIndex = 0;
    var nextArr = [];
    var thirdArr = [];
    if (endIndex == undefined) {
      currentPageIndex = arr.length;
      if (doc.getElementsByClassName('textLayer')[pageNumber]) {
        nextArr = doc.getElementsByClassName('textLayer')[pageNumber].getElementsByTagName('span');
        endIndex = getEndIndex(nextArr, text, text.length, startIndex);
        if (endIndex == undefined && doc.getElementsByClassName('textLayer')[pageNumber + 1]) {
          thirdArr = doc
            .getElementsByClassName('textLayer')
            [pageNumber + 1].getElementsByTagName('span');
          thirdIndex = getEndIndex(thirdArr, text, text.length, 0);
        }
      } else {
        endIndex = undefined;
      }
    } else {
      currentPageIndex = endIndex;
      if (type == 1) {
        if (endIndex && startIndex && endIndex > startIndex + content.length) {
          currentPageIndex = startIndex + content.length;
        }
        //中间标点匹配问题
        // var len = startIndex + content.length + 5;
        // if (startIndex && endIndex && endIndex > (startIndex + content.length + 5)) {
        //   currentPageIndex = len;
        // }
      }
    }
    if (!startIndex) {
      startIndex = 0;
    }
    for (var i = startIndex; i < currentPageIndex + 1; i++) {
      var element = arr[i];
      if (!element) {
        break;
      }
      var hItem = {};
      var cssText = element.style.cssText;

      var spanText = element.innerText;
      var s = spanText.replaceAll(' ', '');
      var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;

      console.log(spanText);
      if (
        text.includes(spanText) ||
        (s && text.includes(s)) ||
        (d && text.includes(d)) ||
        (spanText.substring(2) && text.includes(spanText.substring(2)))
      ) {
        var topLabel = cssText.split('top: ')[1].split(';')[0];
        var leftLabel = cssText.split('left: ')[1].split(';')[0];
        var currentItems = [];
        pageContent.value.forEach((item) => {
          if (item.page == pageNumber) {
            currentItems = item.items;
          }
        });
        for (var m = 0; m < currentItems.length; m++) {
          //  citem.str=citem.str.replaceAll(' ','');
          var citem = currentItems[m];
          if (citem.str == spanText) {
            hItem.width = parseFloat(citem.width);
            hItem.height = parseFloat(citem.height);
            hItem.text = spanText;
            hItem.left = leftLabel;
            hItem.top = topLabel;
            hightList.push(hItem);
            if (hightList.length == 1) {
              gotoElement(element);
            }
            if (text.endsWith(citem.str)) {
              break;
            }
          }
        }
      }
    }
    if (type == 1 && hightList.length == 0) {
      message.info('未匹配到相关内容！');
    }
    // if (type == 2) {
    var nextHightList = [];
    //跨页 目前只考虑跨1页
    if (endIndex != undefined) {
      for (var i = 0; i < nextArr.length; i++) {
        var element = nextArr[i];
        var hItem = {};
        var cssText = element.style.cssText;
        var spanText = element.innerText;
        console.log(spanText);
        if (text.includes(spanText)) {
          var topLabel = cssText.split('top: ')[1].split(';')[0];
          var leftLabel = cssText.split('left: ')[1].split(';')[0];
          var currentItems = [];
          pageContent.value.forEach((item) => {
            if (item.page == pageNumber + 1) {
              currentItems = item.items;
            }
          });
          for (var l = 0; l < currentItems.length; l++) {
            var citem = currentItems[l];
            if (citem.str == spanText) {
              hItem.width = parseFloat(citem.width);
              hItem.height = parseFloat(citem.height);
              hItem.text = spanText;
              hItem.left = leftLabel;
              hItem.top = topLabel;
              nextHightList.push(hItem);
              if (text.endsWith(citem.str)) {
                break;
              }
            }
          }
        }
        if (text.endsWith(spanText)) {
          break;
        }
      }
    } else {
      //跨页 目前只考虑跨2页
      for (var i = 0; i < nextArr.length; i++) {
        var element = nextArr[i];
        var hItem = {};
        var cssText = element.style.cssText;
        var spanText = element.innerText;
        console.log(spanText);

        var topLabel = cssText.split('top: ')[1].split(';')[0];
        var leftLabel = cssText.split('left: ')[1].split(';')[0];
        var currentItems = [];
        pageContent.value.forEach((item) => {
          if (item.page == pageNumber + 1) {
            currentItems = item.items;
          }
        });
        for (var l = 0; l < currentItems.length; l++) {
          var citem = currentItems[l];
          if (citem.str == spanText) {
            hItem.width = parseFloat(citem.width);
            hItem.height = parseFloat(citem.height);
            hItem.text = spanText;
            hItem.left = leftLabel;
            hItem.top = topLabel;
            nextHightList.push(hItem);
            if (text.endsWith(citem.str)) {
              break;
            }
          }
        }
      }
      var thirdHightList = [];
      if (thirdIndex != 0 && thirdIndex != undefined) {
        for (var z = 0; z < thirdIndex + 1; z++) {
          var element = thirdArr[z];
          var hItem = {};
          var cssText = element.style.cssText;
          var spanText = element.innerText;
          console.log(spanText);
          if (text.includes(spanText)) {
            var topLabel = cssText.split('top: ')[1].split(';')[0];
            var leftLabel = cssText.split('left: ')[1].split(';')[0];
            var currentItems = [];
            pageContent.value.forEach((item) => {
              if (item.page == pageNumber + 2) {
                currentItems = item.items;
              }
            });
            for (var l = 0; l < currentItems.length; l++) {
              var citem = currentItems[l];
              if (citem.str == spanText) {
                hItem.width = parseFloat(citem.width);
                hItem.height = parseFloat(citem.height);
                hItem.text = spanText;
                hItem.left = leftLabel;
                hItem.top = topLabel;
                thirdHightList.push(hItem);
                if (text.endsWith(citem.str)) {
                  break;
                }
              }
            }
          }
          if (text.endsWith(spanText)) {
            break;
          }
        }
      }
    }

    //渲染
    var canvas = doc.getElementsByClassName(`page`)[pageNumber - 1];
    const hightDiv = document.createElement('div');
    hightDiv.className = 'highlight-layer flash';
    hightList.forEach((it) => {
      const hDiv = document.createElement('div');
      hDiv.className = 'highlight';
      // 设置内联样式
      hDiv.style.width = it.width + 'px';
      hDiv.style.height = it.height * 1.4 + 'px';
      hDiv.style.left = it.left;
      hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
      hightDiv.appendChild(hDiv);
    });
    canvas.appendChild(hightDiv);
    if (nextHightList && nextHightList.length > 0) {
      //渲染
      var nextCanvas = doc.getElementsByClassName(`page`)[pageNumber];
      const hightDiv = document.createElement('div');
      hightDiv.className = 'highlight-layer flash';
      nextHightList.forEach((it) => {
        const hDiv = document.createElement('div');
        hDiv.className = 'highlight';
        // 设置内联样式
        hDiv.style.width = it.width + 'px';
        hDiv.style.height = it.height * 1.4 + 'px';
        hDiv.style.left = it.left;
        hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
        hightDiv.appendChild(hDiv);
      });
      nextCanvas.appendChild(hightDiv);
    }
    if (thirdHightList && thirdHightList.length > 0) {
      //渲染
      var thirdCanvas = doc.getElementsByClassName(`page`)[pageNumber + 1];
      const hightDiv = document.createElement('div');
      hightDiv.className = 'highlight-layer flash';
      thirdHightList.forEach((it) => {
        const hDiv = document.createElement('div');
        hDiv.className = 'highlight';
        // 设置内联样式
        hDiv.style.width = it.width + 'px';
        hDiv.style.height = it.height * 1.4 + 'px';
        hDiv.style.left = it.left;
        hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
        hightDiv.appendChild(hDiv);
      });
      thirdCanvas.appendChild(hightDiv);
    }
    // }
  }
};
//交集
function commonContent(str1, str2) {
  let result = '';
  for (let i = 0; i < str1.length; i++) {
    if (str2.includes(str1[i])) {
      result += str1[i];
    }
  }
  return result;
}
const getStartIndex = (arr, text, total) => {
  var indexs = [];
  for (var i = 0; i < arr.length; i++) {
    var element = arr[i];
    var spanText = element.innerText;
    console.log('===' + spanText);

    if (
      (spanText && text.startsWith(spanText)) ||
      (spanText && spanText.substring(2) && spanText && text.startsWith(spanText.substring(2))) ||
      (spanText.indexOf('。') > -1 &&
        spanText.split('。')[1] &&
        text.startsWith(spanText.split('。')[1])) ||
      (spanText.endsWith('。') &&
        spanText.split('。')[0] &&
        text.startsWith(spanText.split('。')[0]))
    ) {
      indexs.push(i);
      //   return i;
    }
  }
  if (indexs.length == 0) {
    return 0;
  } else if (indexs.length == 2) {
    console.log(JSON.stringify(indexs));
    return indexs[0] == 0 ? indexs[1] : indexs[0];
  } else {
    return indexs[0];
  }
  //todo 有问题
  // if (count == arr.length) {
  //   start.value = start.value + 1;
  //   text = text.substring(start.value, total);
  //   getStartIndex(arr, text, total);
  // }
};
const getEndIndex = (arr, text, total, startIndex) => {
  for (var i = 0; i < arr.length; i++) {
    var element = arr[i];
    var spanText = element.innerText;
    var e = '';
    if (spanText.endsWith('。')) {
      spanText = spanText.substring(0, spanText.lastIndexOf('。'));
    }
    if (spanText.indexOf('。') > -1) {
      e = spanText.substring(0, spanText.lastIndexOf('。'));
    }
    console.log('===' + spanText);
    if (
      (spanText && text.endsWith(spanText) && spanText.length > 0) ||
      (spanText && spanText.indexOf(text) > -1) ||
      (e && text.endsWith(e))
    ) {
      return i;
    }
  }
};
const heightSingle = (str, flag) => {
  const iframeDocument = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;

  const searchText = str;
  var highlightColor = 'lightblue';

  // 使用DOM操作在iframe中搜索并高亮文本
  const textNodes = iframeDocument.evaluate(
    ".//text()[contains(., '" + searchText + "')]",
    iframeDocument,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null
  );
  var firstFlag = false;
  for (let i = 0, length = textNodes.snapshotLength; i < length; i++) {
    const content = textNodes.snapshotItem(i);
    const textNode = content.textContent;

    const regex = new RegExp(searchText, 'gi');
    var newContent = textNode.replace(regex, (match) => {
      if (match == searchText) {
        if (!firstFlag) {
          firstFlag = true;
          highlightColor = 'yellow';
        } else {
          highlightColor = 'lightblue';
        }
        return `<span  id='hightlight-${searchList.value.length}' style="background-color: ${highlightColor};color: #333;margin-top:-3px;border-radius: 3px;">${match}</span>`;
      }
    });
    if (content.parentNode) {
      var n = content.parentNode;
      console.log('====' + n.offsetTop);
      newContent = '<' + newContent.split('<')[1] + '</span>';
      var h = content.parentNode.innerHTML;
      if (!flag) {
        content.parentNode.innerHTML = h.replace(searchText, newContent);
      }
      if (n) {
        searchList.value.push({
          cs: n.parentNode.className,
          index: searchList.value.length,
          n: n.parentNode
        });
        if (searchList.value.length == 1) {
          // if (!flag) {
          //   locateElement(searchList.value[0].cs, 0);
          // }
          gotoElement(n);
        }
        //大纲只定位一次
        if (flag) {
          break;
        }
      }
    }
    if (!flag) {
      if (i == textNodes.snapshotLength - 1) {
        //查询结束
        emits('search', searchList.value);
      }
    }
  }
};
const removeSourceHightLight = () => {
  //获取页面 ai定位移除
  const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;

  const arr = doc.getElementsByClassName('highlight-layer');
  const l = arr.length;
  for (let i = l - 1; i >= 0; i--) {
    if (arr[i] != null) {
      arr[i].parentNode.removeChild(arr[i]);
    }
  }
};
const removeHighlight = () => {
  removeSourceHightLight();
  if (searchList.value) {
    searchList.value.forEach((item, index) => {
      const iframeDocument =
        iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
      const highlightedSpan = iframeDocument.getElementById('hightlight-' + index);
      if (highlightedSpan != null) {
        const span = highlightedSpan;
        console.log(span.innerHTML);
        setTimeout(() => {
          span.parentNode.replaceChild(document.createTextNode(span.textContent), span);
        }, 10);
      }
    });
  }
  searchList.value = [];
  emits('search', searchList.value);
};
defineExpose({ highlightText, removeHighlight, scrollTo, goLocation, goSourceLocation, location });
</script>

<style scoped lang="scss">
.close-icon {
  position: absolute;

  top: 8px;
  right: 12px;
  cursor: pointer;
}
</style>
<style>
/* 不能用scoped，因为动态创建的元素不会被编译带上hash */
/* 不加上这些css修饰，元素会错位，样式来自vue-pdf-embed这个库 */
.canvasWrapper {
  position: relative;
  /* display: flex;
  justify-content: center; */
}
.page {
  position: relative;
  box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.08);
  margin: 30px auto;
}
.textLayer {
  text-align: initial;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  opacity: 0.2;
  line-height: 1;
  text-size-adjust: none;
  forced-color-adjust: none;
}
.textLayer span,
.textLayer br {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
.highlight-layer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  opacity: 0.15;
  overflow: hidden;
}
.flash {
  animation: flashing 0.6s;
  animation-iteration-count: 2;
}
@keyframes flashing {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 0.15;
  }
}
.highlight {
  background-color: #0076fa;
  position: absolute;
}
</style>
