import { useEffect, useState, useMemo } from 'react';
import MarkdownRenderer from './MarkdownRenderer';
import { X, Copy, Check, Download, PanelRightClose, PanelRightOpen } from 'lucide-react';
import 'highlight.js/styles/github-dark.css';

interface FilePreviewModalProps {
  isOpen: boolean;
  onClose: () => void;
  content: string;
}

// Helper to generate IDs from text
const slugify = (text: string) => {
  return text
    .toString()
    .toLowerCase()
    .trim()
    .replace(/\s+/g, '-')
    .replace(/[^\w\u4e00-\u9fa5-]+/g, '')
    .replace(/-+/g, '-');
};

export default function FilePreviewModal({ isOpen, onClose, content }: FilePreviewModalProps) {
  const [copied, setCopied] = useState(false);
  const [showToc, setShowToc] = useState(false);

  useEffect(() => {
    if (isOpen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = 'unset';
    }
    return () => {
      document.body.style.overflow = 'unset';
    };
  }, [isOpen]);

  // Generate TOC data
  const toc = useMemo(() => {
    const lines = content.split('\n');
    const headers: { level: number; text: string; id: string }[] = [];
    
    // Simple regex to match headers. Note: this won't handle code blocks correctly if they contain #
    // But for a simple TOC it's usually "good enough". 
    // A more robust way would be to traverse the AST, but that requires more setup.
    let inCodeBlock = false;
    
    lines.forEach(line => {
      if (line.trim().startsWith('```')) {
        inCodeBlock = !inCodeBlock;
        return;
      }
      if (inCodeBlock) return;

      const match = line.match(/^(#{1,3})\s+(.+)$/);
      if (match) {
        const level = match[1].length;
        const text = match[2].trim();
        const id = slugify(text);
        headers.push({ level, text, id });
      }
    });
    
    return headers;
  }, [content]);

  if (!isOpen) return null;

  const handleCopy = () => {
    navigator.clipboard.writeText(content);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const handleDownload = () => {
    const blob = new Blob([content], { type: 'text/markdown' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'content.md';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const scrollToHeader = (id: string) => {
    const element = document.getElementById(id);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth' });
    }
  };

  // Custom components for ReactMarkdown to add IDs - Removed as we switched to marked
  // In a full implementation we would configure marked slugger or use a custom renderer for headers
  // For now, TOC scrolling relies on ids that might not be present if we don't add them.
  // marked adds ids to headers by default (gfm: true). 
  // We can verify this or use a simple post-processing/custom renderer if needed.
  // For this "change parser" request, let's stick to default marked behavior first.

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4 animate-in fade-in duration-200">
      <div 
        className="bg-white dark:bg-gray-900 w-full max-w-6xl h-[90vh] rounded-2xl shadow-2xl flex flex-col overflow-hidden animate-in zoom-in-95 duration-200 border border-gray-200 dark:border-gray-800"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-100 dark:border-gray-800 bg-white/50 dark:bg-gray-900/50 backdrop-blur shrink-0">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
                <svg className="w-5 h-5 text-blue-600 dark:text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                </svg>
            </div>
            <div>
                <h3 className="font-medium text-gray-900 dark:text-gray-100">Markdown Preview</h3>
                <p className="text-xs text-gray-500 dark:text-gray-400">Read-only mode</p>
            </div>
          </div>
          <div className="flex items-center gap-2">
            {/* TOC Toggle */}
            {toc.length > 0 && (
                <button 
                    onClick={() => setShowToc(!showToc)}
                    className={`p-2 rounded-lg transition-colors flex items-center gap-2 ${
                        showToc 
                        ? 'text-blue-600 bg-blue-50 dark:text-blue-400 dark:bg-blue-900/20' 
                        : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800'
                    }`}
                    title={showToc ? "Hide Table of Contents" : "Show Table of Contents"}
                >
                    {showToc ? <PanelRightClose size={18} /> : <PanelRightOpen size={18} />}
                </button>
            )}

            <div className="w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1"></div>

            <button 
                onClick={handleCopy}
                className="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors flex items-center gap-2"
                title="Copy content"
            >
                {copied ? <Check size={18} className="text-green-500" /> : <Copy size={18} />}
            </button>
            <button 
                onClick={handleDownload}
                className="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
                title="Download .md"
            >
                <Download size={18} />
            </button>
            <div className="w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1"></div>
            <button 
                onClick={onClose}
                className="p-2 text-gray-500 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
            >
                <X size={20} />
            </button>
          </div>
        </div>

        {/* Body */}
        <div className="flex-1 flex overflow-hidden">
            {/* Content */}
            <div className="flex-1 overflow-y-auto custom-scrollbar p-8 bg-white dark:bg-gray-900">
                <div className="prose dark:prose-invert max-w-none prose-headings:font-semibold prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-code:text-blue-600 dark:prose-code:text-blue-400 prose-pre:bg-gray-50 dark:prose-pre:bg-gray-800 prose-pre:border prose-pre:border-gray-100 dark:prose-pre:border-gray-700 isolate">
                    <MarkdownRenderer 
                        content={content}
                    />
                </div>
            </div>

            {/* TOC Sidebar */}
            {toc.length > 0 && showToc && (
                <div className="w-64 border-l border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/50 backdrop-blur overflow-y-auto custom-scrollbar p-4 animate-in slide-in-from-right-5 duration-200">
                    <h4 className="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4">
                        Table of Contents
                    </h4>
                    <nav className="space-y-1">
                        {toc.map((item, index) => (
                            <button
                                key={`${item.id}-${index}`}
                                onClick={() => scrollToHeader(item.id)}
                                className={`
                                    block w-full text-left px-2 py-1.5 rounded text-sm transition-colors
                                    ${item.level === 1 ? 'font-medium text-gray-900 dark:text-gray-100' : ''}
                                    ${item.level === 2 ? 'pl-4 text-gray-600 dark:text-gray-400' : ''}
                                    ${item.level === 3 ? 'pl-8 text-gray-500 dark:text-gray-500' : ''}
                                    hover:bg-gray-100 dark:hover:bg-gray-800
                                `}
                            >
                                {item.text}
                            </button>
                        ))}
                    </nav>
                </div>
            )}
        </div>
      </div>
    </div>
  );
}
