import React, { useMemo, useEffect, useRef } from 'react';
import { marked } from 'marked';
import DOMPurify from 'dompurify';
import HashtagText from './HashtagText';
import Prism from 'prismjs';

import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-markup';
import '../styles/prism-custom-theme.css';

interface MarkdownRendererProps {
  content: string;
  className?: string;
}

const MarkdownRenderer = React.memo(({ content, className = "" }: MarkdownRendererProps) => {
  const containerRef = React.useRef<HTMLDivElement>(null);

  // Memoize content analysis
  const contentAnalysis = useMemo(() => {
    const hasHashtags = /#[a-zA-Z0-9_]+/.test(content);
    const hasMarkdownLinks = /\[.*?\]\(.*?\)/.test(content);
    const hasMarkdownSyntax = /(\*\*|__|##?|###?|####?|#####?|######?|\*|\n\*|\n-|\n\d+\.)/.test(content);

    return {
      hasHashtags,
      hasMarkdownLinks,
      hasMarkdownSyntax
    };
  }, [content]);

  // Only use HashtagText if content has hashtags but NO markdown syntax at all
  // This preserves hashtag linking for simple text while allowing markdown to render properly
  if (contentAnalysis.hasHashtags && !contentAnalysis.hasMarkdownLinks && !contentAnalysis.hasMarkdownSyntax) {
    return (
      <div className={`prose prose-sm max-w-none dark:prose-invert ${className}`}>
        <HashtagText>{content}</HashtagText>
      </div>
    );
  }

  // Memoize the expensive HTML processing
  const htmlContent = useMemo(() => {
    // Decode HTML entities first if present
    const decodedContent = content
      .replace(/&#x20;/g, ' ')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&amp;/g, '&')
      .replace(/&quot;/g, '"')
      .replace(/&#39;/g, "'");


    // Configure marked options
    marked.setOptions({
      breaks: true,
      gfm: true,
    });

    // Custom renderer to add IDs to headings
    const renderer = new marked.Renderer();
    renderer.heading = ({ text, depth }: { text: string; depth: number }) => {
      const slug = text
        .toLowerCase()
        .trim()
        .replace(/[^\w\s-]/g, '')
        .replace(/[\s_-]+/g, '-')
        .replace(/^-+|-+$/g, '');

      return `<h${depth} id="${slug}">${text}</h${depth}>`;
    };

    marked.use({ renderer });

    // Convert markdown to HTML
    const rawHtml = marked.parse(decodedContent) as string;

    // Helper function to format URL display text
    const formatUrlDisplay = (url: string): string => {
      try {
        // Remove protocol
        let displayUrl = url.replace(/^https?:\/\//, '');

        // Remove www. if present
        displayUrl = displayUrl.replace(/^www\./, '');

        // Truncate if too long (keep domain + some path)
        if (displayUrl.length > 40) {
          const parts = displayUrl.split('/');
          const domain = parts[0];
          const path = parts.slice(1).join('/');

          if (path.length > 20) {
            displayUrl = `${domain}/${path.substring(0, 15)}...`;
          } else {
            displayUrl = `${domain}/${path}`;
          }
        }

        return displayUrl;
      } catch {
        return url;
      }
    };

    // Post-process to add target="_blank", styling, and format link text
    const processedHtml = rawHtml.replace(
      /<a href="([^"]*)"([^>]*)>([^<]*)<\/a>/g,
      (match, href, attrs, text) => {
        // If the link text is the same as the URL (auto-generated), format it nicely
        const isAutoLink = text === href || text.replace(/^https?:\/\//, '') === href.replace(/^https?:\/\//, '');
        const displayText = isAutoLink ? formatUrlDisplay(href) : text;

        return `<a href="${href}"${attrs} target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 underline hover:no-underline transition-colors">${displayText}</a>`;
      }
    );

    return DOMPurify.sanitize(processedHtml, {
      ADD_ATTR: ['target', 'rel', 'class'] // Allow target, rel, and class attributes for links
    });
  }, [content]);

  // Apply syntax highlighting after render
  React.useEffect(() => {
    if (containerRef.current) {
      Prism.highlightAllUnder(containerRef.current);
    }
  }, [htmlContent]);

  return (
    <div
      ref={containerRef}
      className={`prose prose-sm max-w-none dark:prose-invert ${className}`}
      dangerouslySetInnerHTML={{ __html: htmlContent }}
    />
  );
});

MarkdownRenderer.displayName = 'MarkdownRenderer';

export default MarkdownRenderer;