import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { BulbOutlined, InfoCircleOutlined, CheckCircleOutlined, ExclamationCircleOutlined, CloseCircleOutlined } from '@ant-design/icons';
import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw';

export type TocItem = { id: string; text: string; level: number };

function slugify(text: string) {
  return text
    .trim()
    .replace(/\s+/g, '-')
    .replace(/[()（）:/?？、,.。!！'"`]/g, '')
    .toLowerCase();
}

interface MarkdownViewerProps {
  content: string;
  onToc?: (toc: TocItem[]) => void;
}

const MarkdownViewer: React.FC<MarkdownViewerProps> = ({ content, onToc }) => {
  const [toc, setToc] = useState<TocItem[]>([]);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const navigate = useNavigate();

  const components = useMemo(() => {
    const getNodeText = (node: any): string => {
      if (node == null) return '';
      if (typeof node === 'string' || typeof node === 'number') return String(node);
      if (Array.isArray(node)) return node.map(getNodeText).join('');
      if (node.props && node.props.children) return getNodeText(node.props.children);
      return '';
    };
    const Heading = (level: number) =>
      function H(props: any) {
        const childrenText = getNodeText(props.children);
        const id = slugify(childrenText);
        return React.createElement(
          'h' + level,
          { id },
          props.children
        );
      };

    const isExternal = (href?: string) => !!href && (/^https?:\/\//i.test(href) || href.startsWith('//'));
    const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>, href?: string) => {
      if (!href) return;
      if (href.startsWith('#')) {
        e.preventDefault();
        const id = href.slice(1);
        const el = document.getElementById(id);
        if (el) {
          el.scrollIntoView({ behavior: 'smooth', block: 'start' });
          history.replaceState(null, '', `#${id}`);
        }
        return;
      }
      if (href.startsWith('/help')) {
        e.preventDefault();
        navigate(href);
        return;
      }
    };

    return {
      h1: Heading(1),
      h2: Heading(2),
      h3: Heading(3),
      table: (props: any) => (
        <div style={{ overflowX: 'auto' }}>
          <table {...props} />
        </div>
      ),
      code: (props: any) => (
        <code style={{ background: '#f6f7f9', padding: '2px 4px', borderRadius: 4 }} {...props} />
      ),
      a: (props: any) => {
        const href = props?.href as string | undefined;
        const external = isExternal(href);
        return (
          <a
            {...props}
            target={external ? '_blank' : undefined}
            rel={external ? 'noreferrer' : undefined}
            onClick={(e) => {
              if (!external) handleLinkClick(e, href);
              props?.onClick?.(e);
            }}
          />
        );
      },
      img: (props: any) => (
        <img
          style={{ maxWidth: '100%', height: 'auto', display: 'block', margin: '12px auto' }}
          {...props}
        />
      ),
      // Custom: <Tip type="info|warn|success">...children...</Tip>
      tip: (props: any) => {
        const type = props?.node?.properties?.type || 'info';
        const iconName = props?.node?.properties?.['data-icon'];
        const colorMap: Record<string, { bg: string; bd: string; text: string }> = {
          info: { bg: '#f5f9ff', bd: '#d6e4ff', text: '#5b6b8c' },
          warn: { bg: '#fff9f0', bd: '#ffe58f', text: '#ad6800' },
          success: { bg: '#f6fef9', bd: '#d1fadf', text: '#046c4e' },
          danger: { bg: '#fff1f0', bd: '#ffa39e', text: '#a8071a' },
        };
        const theme = colorMap[type] || colorMap.info;
        const iconMap: Record<string, React.ReactNode> = {
          bulb: <BulbOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          info: <InfoCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          check: <CheckCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          success: <CheckCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          warning: <ExclamationCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          warn: <ExclamationCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
          danger: <CloseCircleOutlined style={{ fontSize: 18, color: theme.text, marginTop: 2 }} />,
        };
        const defaultIconByType: Record<string, React.ReactNode> = {
          info: iconMap.info,
          warn: iconMap.warning,
          success: iconMap.success,
          danger: iconMap.danger,
        };
        const iconNode = iconName ? (iconMap[iconName] || defaultIconByType[type]) : defaultIconByType[type] || iconMap.bulb;
        return (
          <div className={`help-tip help-tip-${type}`}
            style={{
              background: theme.bg,
              border: `1px solid ${theme.bd}`,
              color: theme.text,
              padding: '12px 14px',
              borderRadius: 8,
              lineHeight: 1.6,
              margin: '12px 0',
            }}
          >
            <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
              {iconNode}
              <div style={{ flex: 1 }}>{props.children}</div>
            </div>
          </div>
        );
      },
      // Custom: <CardGroup cols="3"> <Card ...>...</Card> ... </CardGroup>
      cardgroup: (props: any) => {
        const colsProp = props?.node?.properties?.cols;
        const cols = Number(colsProp) > 0 ? Number(colsProp) : 3;
        const grid = `repeat(${cols}, minmax(0, 1fr))`;
        return (
          <div className="help-card-group" style={{ display: 'grid', gap: 16, gridTemplateColumns: grid, margin: '12px 0' }}>
            {props.children}
          </div>
        );
      },
      // Custom: <Card title="" href="/path" data-icon="book-open">children</Card>
      card: (props: any) => {
        const p = props?.node?.properties || {};
        const title = p.title || '';
        const href = p.href || '';
        const icon = p['data-icon'] || '';
        const iconStyle: React.CSSProperties = icon
          ? {
              WebkitMaskImage: `url(/resource/icon/${icon}.svg)`,
              maskImage: `url(/resource/icon/${icon}.svg)`,
              WebkitMaskRepeat: 'no-repeat',
              maskRepeat: 'no-repeat',
              WebkitMaskPosition: 'center',
              maskPosition: 'center',
              background: '#1677ff',
              width: 24,
              height: 24,
              display: 'inline-block',
            }
          : {};
        const content = (
          <div className="help-card" style={{
            border: '1px solid #eee',
            borderRadius: 10,
            padding: 16,
            background: '#fff',
            boxShadow: '0 1px 2px rgba(0,0,0,0.03)',
            height: '100%',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              {icon ? <span style={iconStyle} /> : null}
              <div style={{ fontWeight: 600 }}>{title}</div>
            </div>
            <div className="help-card-content" style={{ color: '#555' }}>{props.children}</div>
          </div>
        );
        if (!href) return content;
        const external = isExternal(href);
        return (
          <a
            href={href}
            style={{ textDecoration: 'none' }}
            target={external ? '_blank' : undefined}
            rel={external ? 'noreferrer' : undefined}
            onClick={(e) => {
              if (!external) handleLinkClick(e, href);
            }}
          >
            {content}
          </a>
        );
      },
    } as any;
  }, []);

  useEffect(() => {
    // build toc after render
    const root = containerRef.current;
    if (!root) return;
    const nodes = Array.from(root.querySelectorAll('h1, h2, h3')) as HTMLElement[];
    const items = nodes.map((n) => ({ id: n.id, text: n.textContent || '', level: Number(n.tagName.substring(1)) }));
    setToc(items);
    onToc?.(items);
  }, [content, onToc]);

  return (
    <div ref={containerRef} className="help-markdown">
      {/* Ensure raw HTML elements styled as documentation site */}
      <style>{`
        .help-markdown img{max-width:100%;height:auto;display:block;margin:12px auto;}
        .help-markdown figure{margin:16px auto;max-width:100%;}
        .help-markdown figure img{display:block;margin:0 auto;}
        .help-markdown figcaption{margin-top:8px;color:#666;font-size:12px;text-align:center;}
        .help-card-group{--gap:16px}
        .help-card a{color:inherit}
        /* Typography */
        .help-markdown h1{font-size:28px;line-height:1.35;font-weight:700;margin:32px 0 12px;}
        .help-markdown h2{font-size:24px;line-height:1.4;font-weight:700;margin:28px 0 12px;}
        .help-markdown h3{font-size:20px;line-height:1.45;font-weight:600;margin:24px 0 8px;}
        .help-markdown p{font-size:15.5px;line-height:1.9;margin:10px 0 16px;}
        .help-markdown ul,.help-markdown ol{padding-left:1.4em;margin:8px 0 16px;}
        .help-markdown li{margin:4px 0;}
        .help-markdown strong{font-weight:700;}
        .help-markdown blockquote{border-left:3px solid #e6f4ff;background:#f7fbff;padding:8px 12px;color:#334155;margin:12px 0;}
        /* Success Tip showcase style */
        .help-tip-success{border-radius:14px;padding:16px 18px;border-color:#d1fadf;background:#f6fef9;box-shadow:0 2px 8px rgba(4,108,78,0.04) inset, 0 1px 2px rgba(0,0,0,0.02)}
        .help-tip-success a{color:#0f766e}
        .help-tip-success img{border-radius:12px;box-shadow:0 10px 24px rgba(2,44,34,0.08);}
      `}</style>
      <ReactMarkdown rehypePlugins={[rehypeRaw]} components={components}>
        {content}
      </ReactMarkdown>
    </div>
  );
};

export default MarkdownViewer;
