<template>
  <view class="nana-Parse-container" :style="contentStyle">
    <ParseNodeRender 
      v-for="(node, index) in nodes" 
      :key="index" 
      :node="node" 
      @linkTap="emit('linkTap', $event)"
      @viewTap="emit('viewTap', $event)"
    />
  </view>
</template>

<script setup lang="ts">
import ParseNodeRender from './ParseNodeRender.vue'
import { parse, type DefaultTreeAdapterTypes } from 'parse5'
import { computed, provide, ref, toRef } from 'vue';
import type { ParseNode } from './Parse'

export interface ParseProps {
  /**
   * HTML解析内容
   */
  content?: string|null|undefined;
  /**
   * 标签样式。键为标签名，值为样式
   */
  tagStyle?: Record<string, string>;
  /**
   * 类样式。键为类名，值为样式
   */
  classStyle?: Record<string, string>;
  /**
   * 容器样式
   */
  contentStyle?: any;
}

const emit = defineEmits(['linkTap', 'viewTap']);

const props = withDefaults(defineProps<ParseProps>(), {
  tagStyle: () => ({}),
  classStyle: () => ({}),
  contentStyle: () => ({})
});

const praseImages = ref<string[]>([]);

provide('tagStyle', toRef(props, 'tagStyle'));
provide('classStyle', toRef(props, 'classStyle'));
provide('praseImages', praseImages);

const toObj = (attrs: DefaultTreeAdapterTypes.Element['attrs']) => {
  const obj: Record<string, string> = {};
  for (const attr of attrs) {
    obj[attr.name] = attr.value;
  }
  return obj;
}
// 解析HTML为节点树
const parseHtml = (html: string): ParseNode[] => {
  const nodes: ParseNode[] = [];
  const doc = parse(html);
  praseImages.value = [];
  
  const solveTextNode = (child: DefaultTreeAdapterTypes.TextNode, nodes: ParseNode[], parentTag?: string) => {
    const value = child.value;
    if (value.trim() === '') {
      return null;
    }
    if (value.trim() === '\n') {
      const node: ParseNode = {
        tag: 'br',
      };
      nodes.push(node);
      return node;
    }
    const node: ParseNode = {
      tag: 'text',
      attrs: {
        content: value
      },
      parentTag,
      index: 0
    };
    nodes.push(node);
    return node;
  }
  const traverse = (element: DefaultTreeAdapterTypes.Element, parentTag?: string): ParseNode => {
    const node: ParseNode = {
      tag: element.tagName,
      attrs: toObj(element.attrs),
      children: [],
      parentTag,
      index: 0
    };
    
    // 解析子节点
    if (element.childNodes) {
      let index = 0;
      for (const child of element.childNodes) {
        if (child.nodeName === '#text') {
          const textNode = solveTextNode(child as DefaultTreeAdapterTypes.TextNode, node.children || [], element.tagName);
          if (textNode)
            textNode.index = index++;
        } else if (child.nodeName !== '#comment' && child.nodeName !== '#documentType') {
          const childNode = traverse(child as DefaultTreeAdapterTypes.Element, element.tagName);
          childNode.index = index++;
          node.children?.push(childNode);
          if (childNode.tag === 'img') {
            praseImages.value.push(childNode.attrs?.src as string);
          }
        }
      }
    }
    
    return node;
  };

  let index = 0;
  for (const child of doc.childNodes) {
    if (child.nodeName === '#text') {
      const textNode = solveTextNode(child as DefaultTreeAdapterTypes.TextNode, nodes, 'body');
      if (textNode)
        textNode.index = index++;
    } else if (child.nodeName !== '#documentType') {
      const childNode = traverse(child as DefaultTreeAdapterTypes.Element, 'body');
      childNode.index = index++;
      nodes.push(childNode);
    }
  }
  console.log(doc);
  
  return nodes;
};

// 计算属性，获取解析后的节点树
const nodes = computed(() => parseHtml(props.content || ''));
</script>

<style scoped>
.nana-Parse-container {
  width: 100%;
}
</style>