import React, { useMemo, useState, useEffect, useCallback } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import remarkBreaks from 'remark-breaks';
import rehypeRaw from 'rehype-raw';
import rehypeKatex from 'rehype-katex';
import rehypeHighlight from 'rehype-highlight';
import { useApp } from '../context/AppContext';
import { generateBreadcrumbs, getFileTitle } from '../utils/fileUtils';
import './MarkdownRenderer.css';
import 'katex/dist/katex.min.css';
import 'highlight.js/styles/github.css';

function Breadcrumbs({ filePath }) {
  const breadcrumbs = generateBreadcrumbs(filePath);
  if (breadcrumbs.length === 0) return null;
  return (
    <nav className="breadcrumbs" aria-label="当前位置">
      {breadcrumbs.map((crumb, index) => (
        <span key={crumb.path} className="breadcrumb-item">
          {index > 0 && <span className="breadcrumb-separator">/</span>}
          <span className="breadcrumb-text">{crumb.name}</span>
        </span>
      ))}
    </nav>
  );
}

function CodeBlock({ inline, className, children, ...props }) {
  const match = /language-(\w+)/.exec(className || '');
  const language = match ? match[1] : '';

  if (inline) {
    return (
      <code className="inline-code" {...props}>
        {children}
      </code>
    );
  }

  return (
    <div className="code-block-wrapper">
      {language && (
        <div className="code-block-header">
          <span className="code-language">{language}</span>
        </div>
      )}
      <pre className={className} {...props}>
        <code>{children}</code>
      </pre>
    </div>
  );
}

function CustomLink({ href, children, ...props }) {
  if (href && href.startsWith('[[') && href.endsWith(']]')) {
    const linkText = href.slice(2, -2);
    return (
      <span className="internal-link" title={内部链接: }>
        {children || linkText}
      </span>
    );
  }

  const isExternal = href && /^(https?:)?\/\//.test(href);
  return (
    <a
      href={href}
      target={isExternal ? '_blank' : '_self'}
      rel={isExternal ? 'noopener noreferrer' : undefined}
      className={isExternal ? 'external-link' : 'internal-link'}
      {...props}
    >
      {children}
      {isExternal && <span className="external-link-icon" aria-hidden>🔗</span>}
    </a>
  );
}

function CustomTable({ children, ...props }) {
  return (
    <div className="table-wrapper">
      <table {...props}>{children}</table>
    </div>
  );
}

function useHeadings(content) {
  return useMemo(() => {
    const headingRegex = /^(#{1,4})\s+(.+)$/gm;
    const headings = [];
    let match;

    while ((match = headingRegex.exec(content)) !== null) {
      const [, hashes, text] = match;
      const level = hashes.length;
      if (level > 4) continue;

      const plainText = text.replace(/[*_~]/g, '').trim();
      const id = plainText
        .toLowerCase()
        .replace(/[^a-z0-9\u00C0-\u024f\u4e00-\u9fa5\s-]/g, '')
        .replace(/\s+/g, '-');

      headings.push({ id, text: plainText, level });
    }

    return headings;
  }, [content]);
}

function TableOfContents({ headings }) {
  if (headings.length === 0) return null;

  return (
    <aside className="content-toc" aria-label="目录">
      <h3>目录</h3>
      <ul className="toc-list">
        {headings.map((heading) => (
          <li key={heading.id} className="toc-item">
            <a
              className={	oc-link level-}
              href={#}
            >
              {heading.text}
            </a>
          </li>
        ))}
      </ul>
    </aside>
  );
}

export default function MarkdownRenderer() {
  const { currentFile, currentContent, isLoading, sidebarOpen } = useApp();
  const [activeHeading, setActiveHeading] = useState(null);
  const headings = useHeadings(currentContent);

  useEffect(() => {
    if (typeof window === 'undefined' || headings.length === 0) {
      return undefined;
    }

    const observer = new IntersectionObserver(
      (entries) => {
        const visible = entries
          .filter((entry) => entry.isIntersecting)
          .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);

        if (visible[0]) {
          setActiveHeading(visible[0].target.id);
        }
      },
      {
        rootMargin: '-40% 0px -50% 0px',
        threshold: [0, 1],
      }
    );

    headings.forEach((heading) => {
      const element = document.getElementById(heading.id);
      if (element) {
        observer.observe(element);
      }
    });

    return () => {
      headings.forEach((heading) => {
        const element = document.getElementById(heading.id);
        if (element) {
          observer.unobserve(element);
        }
      });
      observer.disconnect();
    };
  }, [headings]);

  const renderHeading = useCallback((Tag) => ({ children, ...props }) => {
    const text = React.Children.toArray(children)
      .map((child) => {
        if (typeof child === 'string') return child;
        if (React.isValidElement(child) && typeof child.props.children === 'string') {
          return child.props.children;
        }
        return '';
      })
      .join(' ')
      .trim();

    const id = text
      .toLowerCase()
      .replace(/[^a-z0-9\u00C0-\u024f\u4e00-\u9fa5\s-]/g, '')
      .replace(/\s+/g, '-');

    return (
      <Tag id={id} {...props}>
        <a href={#} aria-hidden className="heading-anchor">
          #
        </a>
        {children}
      </Tag>
    );
  }, []);

  const components = useMemo(() => ({
    code: CodeBlock,
    a: CustomLink,
    table: CustomTable,
    h1: renderHeading('h1'),
    h2: renderHeading('h2'),
    h3: renderHeading('h3'),
    h4: renderHeading('h4'),
    blockquote: ({ children, ...props }) => {
      const childText = React.Children.toArray(children)
        .map((child) => {
          if (typeof child === 'string') return child.trim();
          if (
            React.isValidElement(child) &&
            typeof child.props.children === 'string'
          ) {
            return child.props.children.trim();
          }
          return '';
        })
        .join(' ');

      const calloutMatch = childText.match(/^\s*\[(info|warning|danger|success)\]\s*/i);
      const calloutType = calloutMatch ? calloutMatch[1].toLowerCase() : null;

      return (
        <blockquote
          className={custom-blockquote}
          {...props}
        >
          {children}
        </blockquote>
      );
    },
    img: ({ alt, ...props }) => (
      <figure className="markdown-image">
        <img alt={alt} {...props} />
        {alt && <figcaption>{alt}</figcaption>}
      </figure>
    ),
    ol: ({ ordered, ...props }) => <ol className="ordered-list" {...props} />,
    ul: ({ ordered, ...props }) => <ul className="unordered-list" {...props} />,
    li: ({ checked, children, ...props }) => (
      <li
        className={list-item}
        {...props}
      >
        {children}
      </li>
    ),
  }), [renderHeading]);

  useEffect(() => {
    if (!activeHeading) return undefined;

    const tocLinks = document.querySelectorAll('.toc-link');
    tocLinks.forEach((link) => {
      if (link.getAttribute('href') === #) {
        link.classList.add('active');
      } else {
        link.classList.remove('active');
      }
    });

    return () => {
      tocLinks.forEach((link) => link.classList.remove('active'));
    };
  }, [activeHeading, headings]);

  if (!currentFile) {
    return (
      <div className={content-area }>
        <div className="welcome-message">
          <div className="welcome-content">
            <h1>🌱 欢迎来到萌芽笔记</h1>
            <p>请从左侧导航栏选择一个笔记文件开始阅读</p>
            <div className="welcome-features">
              <div className="feature-item">
                <span className="feature-icon">📝</span>
                <span>支持完整的Markdown语法</span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">🎨</span>
                <span>代码语法高亮</span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">📊</span>
                <span>数学公式与图表</span>
              </div>
              <div className="feature-item">
                <span className="feature-icon">📱</span>
                <span>移动端友好布局</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  const fileTitle = getFileTitle(currentFile.split('/').pop(), currentContent);
  const hasHeadings = headings.length > 0;

  return (
    <div className={content-area }>
      <div className="content-header">
        <Breadcrumbs filePath={currentFile} />
        <h1 className="content-title">{fileTitle}</h1>
      </div>

      <div className={content-body }>
        <div className="markdown-pane">
          {isLoading ? (
            <div className="loading-content">
              <div className="loading-spinner" aria-hidden />
              <span>加载中...</span>
            </div>
          ) : (
            <div className="markdown-content">
              <ReactMarkdown
                remarkPlugins={[remarkGfm, remarkMath, remarkBreaks]}
                rehypePlugins={[rehypeRaw, rehypeKatex, rehypeHighlight]}
                components={components}
              >
                {currentContent}
              </ReactMarkdown>
            </div>
          )}
        </div>

        {hasHeadings && <TableOfContents headings={headings} />}
      </div>
    </div>
  );
}
