import { Component, ElementRef, Input, AfterViewInit, ViewChild, Output, EventEmitter } from '@angular/core';

import * as markmap from 'markmap-view';
import { Markmap, loadCSS, loadJS } from 'markmap-view';

import { Transformer, builtInPlugins } from 'markmap-lib';
// import "../../../node_modules/webfontloader/webfontloader.js";


@Component({
  selector: 'comp-markmap',
  templateUrl: './comp-markmap.component.html',
  styleUrls: ['./comp-markmap.component.scss'],
  standalone: true,
})
export class CompMarkmapComponent implements AfterViewInit {

  @ViewChild("mapView") mapView: ElementRef | undefined
  @Input() markdown: string = ""
  @Input() height: string = "350px";
  @Input() nodeStates: { [key: string]: boolean } = {};

  private currentMarkmap?: Markmap;
  private isLoading = false;

  constructor() { }

  ngAfterViewInit() {
    this.loadMarkMap();
  }

  // 添加一个方法来提取markdown中的标题
  extractTitle(markdown: string): string {
    // 查找以 # 开头的第一行
    const titleMatch = markdown.match(/^#\s+(.+)$/m);
    if (titleMatch && titleMatch[1]) {
      return titleMatch[1].trim();
    }
    return '未命名计划';
  }

  // 添加一个输出事件，用于通知父组件标题变化
  @Output() titleExtracted = new EventEmitter<string>();

  // 添加事件发射器
  @Output() nodeStateChange = new EventEmitter<{ nodeId: string, checked: boolean }>();

  loadMarkMap() {
    if (this.isLoading || !this.mapView?.nativeElement || !this.markdown) {
      return;
    }

    this.isLoading = true;

    try {
      const svg = this.mapView.nativeElement;
      while (svg.firstChild) {
        svg.removeChild(svg.firstChild);
      }

      const transformer = new Transformer([...builtInPlugins]);
      const { root, features } = transformer.transform(this.markdown);
      const assets = transformer.getAssets();

      assets.scripts?.forEach((item: any) => {
        if (item.data?.src?.endsWith("webfontloader.js")) {
          item.data.src = "assets/markmap/webfontloader.js";
        }
      });

      assets.styles?.forEach((item: any) => {
        if (item.data?.src?.endsWith("katex.min.css")) {
          item.data.src = "assets/markmap/katex.min.css";
        }
        if (item.data?.src?.endsWith("default.min.css")) {
          item.data.src = "assets/markmap/default.min.css";
        }
      });

      if (assets.styles) {
        loadCSS(assets.styles);
        if (assets.scripts) {
          loadJS(assets.scripts, {
            getMarkmap: () => markmap,
          }).then(() => {
            const svgEl = this.mapView?.nativeElement;
            if (svgEl) {
              const options = {
                autoFit: true,
                center: true,
                fitRatio: 0.95,
                duration: 500,
                maxWidth: 800,
                nodeFormatter: (node: any) => {
                  if (node.depth > 0) {
                    const isChecked = this.nodeStates[node.id] ? 'checked' : '';
                    const originalContent = node.content;
                    node.content = `
                      <div style="display: flex; align-items: center; gap: 8px;">
                        <input type="checkbox" ${isChecked} 
                          data-node-id="${node.id}" 
                          class="node-checkbox" 
                          style="width: 16px; height: 16px; cursor: pointer;">
                        <span>${originalContent}</span>
                      </div>
                    `;
                  }
                  return node;
                },
                htmlLabels: true,
                onClick: (node: any, event: any) => {
                  const checkbox = event.target.closest('.node-checkbox');
                  if (checkbox) {
                    event.stopPropagation();
                    const nodeId = checkbox.getAttribute('data-node-id');
                    const checked = checkbox.checked;
                    this.onNodeCheckChange(nodeId, checked);
                  }
                }
              };
              this.currentMarkmap = Markmap.create(svgEl, options, root);

              Object.entries(this.nodeStates).forEach(([nodeId, checked]) => {
                const checkbox = svgEl.querySelector(`[data-node-id="${nodeId}"]`);
                if (checkbox) {
                  (checkbox as HTMLInputElement).checked = checked;
                }
              });

              const title = this.extractTitle(this.markdown);
              this.titleExtracted.emit(title);
            }
            this.isLoading = false;
          }).catch(() => {
            this.isLoading = false;
          });
        }
      }
    } catch (error) {
      console.error('Error loading markmap:', error);
      this.isLoading = false;
    }
  }

  // 添加节点状态变化处理方法
  private onNodeCheckChange(nodeId: string, checked: boolean) {
    // 发出事件通知父组件
    this.nodeStateChange.emit({ nodeId, checked });
  }
}
