import { onMounted, onUnmounted, reactive, toRefs } from 'vue';

/**
 * 朗读API
 * @param musicContent 阅读内容
 * @returns
 */
export const useSpeak = (musicContent?: string, selectionCouser?: string) => {
  const _musicContent = musicContent ? '#' + musicContent : '#musicContent';
  const _selectionCouser = selectionCouser
    ? '#' + selectionCouser
    : '#selectionCouser';
  const state = reactive({
    showDom: false,
    synth: null as any,
    // 选中的索引
    selectOptions: {
      startIndex: 0,
      anchorOffset: 0, // 开始段落的偏移值
      endIndex: 0,
      focusOffset: 0 // 结束段落的偏移值
    },
    isSpeak: false // 是否在播放
  });

  // 函数：递归处理节点
  const processNode = (node: any) => {
    const result = document.createDocumentFragment();
    node.childNodes?.forEach((child: any) => {
      if (child.nodeType === Node.TEXT_NODE) {
        // 按标点符号分割文本
        const sentences = child.textContent.split(/(?<=[,，;；。])\s*/);
        sentences?.forEach((sentence: any) => {
          if (sentence.trim()) {
            const customTag = document.createElement('label');
            customTag.textContent = sentence.trim();
            customTag.classList.add('speak-label');
            result.appendChild(customTag);
          }
        });
      } else if (child.nodeType === Node.ELEMENT_NODE) {
        const element = document.createElement(child.nodeName.toLowerCase());
        // 复制原有的属性
        Array.from(child.attributes).forEach((attr: any) => {
          element.setAttribute(attr.name, attr.value);
        });
        // 递归处理子节点
        const processedChildren = processNode(child);
        element.appendChild(processedChildren);
        result.appendChild(element);
      }
    });

    return result;
  };

  // 选中的方向
  const checkSelectionDirection = (selection: any) => {
    if (selection.rangeCount > 0) {
      const anchorNode = selection.anchorNode;
      const anchorOffset = selection.anchorOffset;
      const focusNode = selection.focusNode;
      const focusOffset = selection.focusOffset;

      // 检查是否在同一节点内选择
      if (anchorNode === focusNode) {
        if (anchorOffset < focusOffset) {
          return 'up';
        } else {
          return 'down';
        }
      } else {
        // 检查不同节点的选择情况
        const range = selection.getRangeAt(0);
        const startContainer = range.startContainer;
        const endContainer = range.endContainer;

        if (startContainer === anchorNode && endContainer === focusNode) {
          return 'up';
        } else {
          return 'down';
        }
      }
    } else {
      return 'up';
    }
  };
  const getSelectText = () => {
    const selection: any = window.getSelection();
    const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
    // if (range) {
    //   const startNode = range.startContainer;
    //   let currentParagraph = startNode;
    //   while (
    //     currentParagraph.nodeType !== Node.ELEMENT_NODE ||
    //     currentParagraph.tagName !== 'P'
    //   ) {
    //     currentParagraph = currentParagraph.parentNode;
    //   }
    //   range.setEnd(currentParagraph, currentParagraph.childNodes.length);
    //   selection.removeAllRanges();
    //   selection.addRange(range);
    // }
    // console.log(selection, 'selection.selectAllChildren()')
    if (selection.toString().length > 0) {
      state.showDom = true;
      const textContainer: any = document.querySelector(_musicContent);
      const sentences: any =
        textContainer?.querySelectorAll('label.speak-label');
      let startIndex = 0,
        anchorOffset = 0,
        endIndex = 0,
        focusOffset = 0;
      // console.log(selection, 'selection');
      // sentences.forEach((item: any) => {
      //   console.log(selection.containsNode(item), '---', item)
      // })

      // 都为0的情况下判断为选中某一个段
      if (selection.focusOffset === 0 && selection.anchorOffset === 0) {
        // 查找起始和结束节点的最近的元素父节点
        const anchorNode = selection.anchorNode;
        const startParagraph = anchorNode.parentNode.parentElement;

        const firstNode = startParagraph.childNodes[0];
        const endNode =
          startParagraph.childNodes[startParagraph.childNodes.length - 1];

        sentences?.forEach((element: any, index: number) => {
          if (element === firstNode) {
            startIndex = index;
            anchorOffset = 0;
          }
          if (element === endNode) {
            endIndex = index;
            focusOffset = endNode.textContent.length;
          }
        });
      } else {
        const direction = checkSelectionDirection(selection);
        const firstNode =
          direction === 'up'
            ? selection.anchorNode.parentNode
            : selection.focusNode.parentNode;
        const endNode =
          direction === 'down'
            ? selection.anchorNode.parentNode
            : selection.focusNode.parentNode;
        if (direction === 'up') {
          anchorOffset = selection.anchorOffset;
          focusOffset = selection.focusOffset;
        } else {
          anchorOffset = selection.focusOffset;
          focusOffset = selection.anchorOffset;
        }
        sentences?.forEach((element: any, index: number) => {
          if (element === firstNode) {
            startIndex = index;
            anchorOffset =
              direction === 'up'
                ? selection.anchorOffset
                : selection.focusOffset;
          }
          if (element === endNode) {
            endIndex = index;
            focusOffset =
              direction === 'down'
                ? selection.anchorOffset
                : selection.focusOffset;
          }
        });
      }

      state.selectOptions.startIndex = startIndex;
      state.selectOptions.anchorOffset = anchorOffset;
      state.selectOptions.endIndex = endIndex;
      state.selectOptions.focusOffset = focusOffset;
    } else {
      state.showDom = false;
    }

    // 判断选中的类型
    setTimeout(() => {
      if (selection.type !== 'Range') {
        state.showDom = false;
      }
    }, 200);

    if (range && !selection.isCollapsed) {
      // 获取选中文本的坐标
      // const rect = range.getBoundingClientRect();
      const rects = range.getClientRects();

      if (rects.length > 0) {
        // console.log(rects, 'rects', range);
        const firstRect = rects[rects.length - 1];
        const x = firstRect.right;
        const y = firstRect.top;
        // const bottom = firstRect.bottom;
        const fHeight = firstRect.height;
        const musicContent: any = document.querySelector(_musicContent);
        const parentRect: any = musicContent?.getBoundingClientRect();
        const showDom: any = document.querySelector(_selectionCouser);
        const showDomRect = showDom?.getBoundingClientRect();
        if (showDom) {
          // 判断 上边超出边界
          showDom.style.top =
            (
              y -
              parentRect?.top +
              (showDomRect.height + fHeight / 2) +
              musicContent?.scrollTop
            ).toFixed(2) + 'px';

          if (parentRect?.right - x >= parentRect?.width - showDomRect.width) {
            showDom.style.right =
              (parentRect?.width - showDomRect.width).toFixed(2) + 'px';
            showDom.style.left = 'auto';
          } else {
            showDom.style.right = (parentRect?.right - x - 6).toFixed(2) + 'px';
            showDom.style.left = 'auto';
          }
        }
      }
    }
  };

  /** 开始朗读 */
  const onTextStart = () => {
    onCloseSpeak();
    onSpeak({
      startIndex: state.selectOptions.startIndex,
      anchorOffset: state.selectOptions.anchorOffset
    });
  };

  /** 只读这段 */
  const onTextReadOnly = () => {
    onCloseSpeak();
    onSpeak(state.selectOptions);
  };

  function clearSelection() {
    if (window.getSelection) {
      window.getSelection()?.removeAllRanges(); // 清除选中区域
    } else if ((document as any).selection) {
      (document as any).selection.empty(); // 清除选中区域（IE 8 或更早）
    }
    state.showDom = false;
    // state.selectOptions.startIndex = 0;
    // state.selectOptions.anchorOffset = 0;
    // state.selectOptions.endIndex = 0;
    // state.selectOptions.focusOffset = 0;
  }

  // 清除所有高亮
  function clearAllHighlights() {
    const textContainer: any = document.querySelector(_musicContent);
    const highlights = document.querySelectorAll('.showBgColor');
    highlights.forEach(h => {
      if (h.classList.contains('speak-label')) {
        h.classList.toggle('showBgColor');
      } else {
        const parent: any = h.parentNode;
        const textContent: any = h.textContent;
        parent.replaceChild(document.createTextNode(textContent), h);
      }
    });
    // 合并相邻的文本节点
    textContainer?.normalize();
  }

  /** 关闭朗读 */
  const onCloseSpeak = () => {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    // responsiveVoice.cancel();
    state.synth?.cancel();
    state.isSpeak = false;
    const textContainer: any = document.querySelector(_musicContent);
    const sentences: any = textContainer?.querySelectorAll('label.speak-label');
    sentences?.forEach((sentence: any, i: number) => {
      sentence.classList.toggle('highlight', i === -1);
    });

    clearAllHighlights();
    clearSelection();
  };

  /** 全文朗读 */
  const onAllSpeak = () => {
    clearSelection();
    try {
      onSpeak({
        startIndex: 0
      });
    } catch (e: any) {
      console.log(e, '12');
    }
  };

  // 开始播放
  const onSpeak = (options: {
    startIndex: number;
    endIndex?: number;
    anchorOffset?: number;
    focusOffset?: number;
  }) => {
    const textContainer: any = document.querySelector(_musicContent);
    const sentences: any = textContainer?.querySelectorAll('label.speak-label');

    // console.log(options, '--endIndex');
    let currentSentenceIndex = options.startIndex || 0;
    const end =
      options.endIndex === undefined ? sentences.length - 1 : options.endIndex;

    // 高亮显示
    const highlightSentence = (index: number) => {
      sentences?.forEach((sentence: any, i: number) => {
        sentence.classList.toggle('highlight', i === index);
      });
      // 滚动到高亮的部分
      const highlightText = textContainer?.querySelector('.highlight');
      // highlightText?.scrollIntoView({
      //   behavior: 'smooth',
      //   block: 'center'
      // });
      scrollToElement(highlightText);
    };

    function getOffsetTopRelativeToParent(element: any, parent: any) {
      let offsetTop = 0;
      while (element && element !== parent) {
        offsetTop += element.offsetTop;
        element = element.offsetParent;
      }
      return offsetTop;
    }

    function scrollToElement(element: any) {
      const musicContent: any = document.querySelector(_musicContent);
      const musicRect = musicContent.getBoundingClientRect();

      const diffTop = getOffsetTopRelativeToParent(element, musicContent);
      const musicHeight = musicRect.height / 2;
      let height = 0;
      // console.log(getOffsetTopRelativeToParent(element, musicContent), '12121');
      if (diffTop - musicHeight >= 0) {
        height = diffTop - musicHeight;
      } else {
        height = 0;
      }

      document.querySelector(_musicContent)?.scrollTo({
        top: height,
        behavior: 'smooth'
      });
    }

    // 初始化高亮显示
    const initLightText = () => {
      sentences?.forEach((sentence: any, i: number) => {
        if (i >= currentSentenceIndex && i <= end) {
          const text = sentence.textContent;

          if (currentSentenceIndex === end) {
            const range = document.createRange();
            range.setStart(sentence.firstChild, options.anchorOffset || 0);
            range.setEnd(
              sentence.firstChild,
              options?.focusOffset || text.length
            );
            const label = document.createElement('label');
            label.classList.add('showBgColor');
            range.surroundContents(label);
          } else {
            if (currentSentenceIndex === i) {
              const range = document.createRange();
              range.setStart(sentence.firstChild, options.anchorOffset || 0);
              range.setEnd(sentence.firstChild, text.length);
              const label = document.createElement('label');
              label.classList.add('showBgColor');
              range.surroundContents(label);
            } else if (end === i) {
              const range = document.createRange();
              range.setStart(sentence.firstChild, 0);
              range.setEnd(
                sentence.firstChild,
                options?.focusOffset || text.length
              );
              const label = document.createElement('label');
              label.classList.add('showBgColor');
              range.surroundContents(label);
            } else {
              sentence.classList.add('showBgColor');
            }
          }
        }
        // sentence.classList.toggle('highlight', i === index);
      });
    };

    // 开始播放
    const speaker = () => {
      try {
        state.synth = window.speechSynthesis;

        // 如果当前正在播放，先暂停
        if (state.synth.speaking) {
          state.synth.cancel(); // 取消当前播放
        }

        let sentence = sentences[currentSentenceIndex].textContent;
        if (sentence.length <= 0) {
          console.error('暂无播放内容');
          return;
        }
        // 判断是否为选中的内容播放
        if (
          options.startIndex === options.endIndex &&
          options.endIndex !== undefined
        ) {
          sentence = sentence.substr(
            options.anchorOffset,
            (options.focusOffset || 0) - (options.anchorOffset || 0)
          );
        } else {
          if (options.startIndex === currentSentenceIndex) {
            sentence = sentence.substr(options.anchorOffset, sentence.length);
          }
          if (options.endIndex === currentSentenceIndex) {
            sentence = sentence.substr(0, options.focusOffset);
          }
        }

        const replaceText = ['长笛', '打击乐', '乐曲', '曲'];
        const afterReplaceText = ['尝笛', '打击月', '月取', '取'];

        if (sentence) {
          replaceText.forEach((item: string, index: number) => {
            if (sentence.includes(item)) {
              const regex = new RegExp(item, 'g');
              sentence = sentence.replace(regex, afterReplaceText[index]);
            }
          });
        }

        const utterance = new SpeechSynthesisUtterance(sentence);
        utterance.lang = 'zh-CN';
        utterance.volume = 1;
        utterance.rate = 0.8; // 语速 0.1到10
        utterance.pitch = 1.5; // 范围从0（最小）到2（最大）
        // utterance.text = sentence;

        if (utterance) {
          utterance.onstart = null;
          utterance.onend = null;
          utterance.onerror = null;
        }

        utterance.onstart = () => {
          state.isSpeak = true;
          highlightSentence(currentSentenceIndex);
        };
        utterance.onend = () => {
          console.log('朗读结束');
          currentSentenceIndex++;
          if (currentSentenceIndex <= end && state.isSpeak) {
            speaker(); // 继续下一个句子
          } else {
            currentSentenceIndex = 0; // 结束后重置索引
            highlightSentence(-1); // 清除高亮
            clearAllHighlights();
            state.isSpeak = false;
          }
        };
        utterance.onerror = () => {
          currentSentenceIndex++;
          if (currentSentenceIndex <= end && state.isSpeak) {
            speaker(); // 继续下一个句子
          } else {
            state.isSpeak = false;
          }
        };
        setTimeout(() => {
          state.synth.speak(utterance);
        }, 80);
      } catch (e) {
        console.log(e, 'e');
      }
    };

    speaker();

    initLightText();
  };

  const onDestory = () => {
    document.removeEventListener('mouseup', getSelectText);
    document.removeEventListener('touchend', getSelectText);
    onCloseSpeak();
  };

  onMounted(async () => {
    document.addEventListener('mouseup', getSelectText);
    document.addEventListener('touchend', getSelectText);
  });

  onUnmounted(() => {
    onDestory();
  });

  return {
    ...toRefs(state),
    onAllSpeak,
    onTextStart,
    onDestory,
    onCloseSpeak,
    onTextReadOnly,
    processNode
  };
};
