import { useState } from 'react';
import { X, Check, Copy, Download, Code2, Image as ImageIcon, FileText, Loader2, LucideIcon } from 'lucide-react';
import { RecognitionResult } from '../types';
import { generateImageFromElement, copyImageToClipboard, downloadImage } from '../lib/imageGenerator';
import { API_BASE_URL } from '../config/env';
import { tokenManager } from '../lib/api';
import { trackExportEvent } from '../lib/analytics';
import { useLanguage } from '../contexts/LanguageContext';
import toast, { Toaster } from 'react-hot-toast';

interface ExportSidebarProps {
  isOpen: boolean;
  onClose: () => void;
  result: RecognitionResult | null;
}

type ExportCategory = 'Code' | 'Image' | 'File';

interface ExportOption {
  id: string;
  label: string;
  category: ExportCategory;
  getContent: (result: RecognitionResult) => string | null;
  isDownload?: boolean; // If true, triggers file download instead of copy
  extension?: string;
}

export default function ExportSidebar({ isOpen, onClose, result }: ExportSidebarProps) {
  const { t } = useLanguage();
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [exportingId, setExportingId] = useState<string | null>(null);

  if (!result) return null;

  const exportOptions: ExportOption[] = [
    // Code Category
    {
      id: 'markdown',
      label: 'Markdown',
      category: 'Code',
      getContent: (r) => r.markdown_content
    },
    {
      id: 'latex',
      label: 'LaTeX',
      category: 'Code',
      getContent: (r) => r.latex_content
    },
    {
      id: 'latex_inline',
      label: 'LaTeX (Inline)',
      category: 'Code',
      getContent: (r) => {
        if (!r.latex_content) return null;
        // Remove existing delimiters like \[ \], \( \), $$, or $
        let content = r.latex_content.trim();
        content = content.replace(/^\\\[/, '').replace(/\\\]$/, '');
        content = content.replace(/^\\\(/, '').replace(/\\\)$/, '');
        content = content.replace(/^\$\$/, '').replace(/\$\$$/, '');
        content = content.replace(/^\$/, '').replace(/\$$/, '');
        content = content.trim();
        return `\\(${content}\\)`;
      }
    },
    {
      id: 'latex_display',
      label: 'LaTeX (Display)',
      category: 'Code',
      getContent: (r) => {
        if (!r.latex_content) return null;
        // Remove existing delimiters like \[ \], \( \), $$, or $
        let content = r.latex_content.trim();
        content = content.replace(/^\\\[/, '').replace(/\\\]$/, '');
        content = content.replace(/^\\\(/, '').replace(/\\\)$/, '');
        content = content.replace(/^\$\$/, '').replace(/\$\$$/, '');
        content = content.replace(/^\$/, '').replace(/\$$/, '');
        content = content.trim();
        return `\\[${content}\\]`;
      }
    },
    {
      id: 'mathml',
      label: 'MathML',
      category: 'Code',
      getContent: (r) => r.mathml_content
    },
    {
      id: 'mathml_mml',
      label: 'MathML (MML)',
      category: 'Code',
      getContent: (r) => r.mml
    },
    // Image Category
    {
      id: 'rendered_image',
      label: 'Rendered Image',
      category: 'Image',
      getContent: (r) => r.markdown_content,
    },
    // File Category
    {
      id: 'docx',
      label: 'DOCX',
      category: 'File',
      getContent: (r) => r.markdown_content,
      isDownload: true,
      extension: 'docx'
    }
  ];

  // Handle DOCX export via API
  const handleFileExport = async (type: 'docx') => {
    if (!result?.id) return;

    setExportingId(type);
    try {
      const token = tokenManager.getToken();
      const response = await fetch(`${API_BASE_URL}/task/export`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token ? { 'Authorization': token } : {}),
        },
        body: JSON.stringify({
          task_no: result.id,
          type: type,
        }),
      });

      if (!response.ok) {
        throw new Error(`Export failed: ${response.statusText}`);
      }

      // Get the blob from response
      const blob = await response.blob();

      // Create download link
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `export.${type}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);

      setCopiedId(type);
      setTimeout(() => {
        setCopiedId(null);
        onClose();
      }, 1000);
    } catch (err) {
      console.error('Export failed:', err);
      alert(t.export.failed);
    } finally {
      setExportingId(null);
    }
  };

  // Handle image generation from Markdown preview
  const handleImageGeneration = async (action: 'copy' | 'download') => {
    // We capture the rendered result directly from the DOM
    const elementId = 'markdown-preview-content';

    setExportingId('rendered_image');

    try {
      const dataUrl = await generateImageFromElement(elementId, {
        format: 'png',
        scale: 2,
        padding: 24,
      }) as string;

      if (action === 'copy') {
        await copyImageToClipboard(dataUrl);
      } else {
        downloadImage(dataUrl, 'rendered_image.png');
      }

      setCopiedId('rendered_image');
      setTimeout(() => {
        setCopiedId(null);
        onClose();
      }, 1000);
    } catch (err) {
      console.error('Failed to generate image:', err);
      alert(`${t.export.imageFailed}: ${err}`);
    } finally {
      setExportingId(null);
    }
  };

  const handleAction = async (option: ExportOption) => {
    // Analytics tracking
    if (result?.id) {
      trackExportEvent(
        result.id,
        option.id,
        exportOptions.map(o => o.id)
      );
    }

    // Handle DOCX export via API
    if (option.id === 'docx') {
      await handleFileExport('docx');
      return;
    }

    // Handle image generation from Markdown
    if (option.id === 'rendered_image') {
      await handleImageGeneration('copy');
      return;
    }

    const content = option.getContent(result);

    // Check if content is empty and show toast
    if (!content) {
      toast.error(t.export.noContent, {
        duration: 2000,
        position: 'top-center',
        style: {
          background: '#fff',
          color: '#1f2937',
          padding: '16px 20px',
          borderRadius: '12px',
          boxShadow: '0 10px 40px rgba(59, 130, 246, 0.15), 0 2px 8px rgba(59, 130, 246, 0.1)',
          border: '1px solid #dbeafe',
          fontSize: '14px',
          fontWeight: '500',
          maxWidth: '900px',
          lineHeight: '1.5',
        },
        iconTheme: {
          primary: '#ef4444',
          secondary: '#ffffff',
        },
      });
      return;
    }

    setExportingId(option.id);

    try {
      if (option.isDownload) {
        // Simulate download (for other file types if any)
        const blob = new Blob([content], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `export.${option.extension}`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      } else {
        // Standard Text Copy
        await navigator.clipboard.writeText(content);
      }

      setCopiedId(option.id);
      setTimeout(() => {
        setCopiedId(null);
        onClose(); // Auto close after action
      }, 1000);

    } catch (err) {
      console.error('Action failed:', err);
      toast.error(t.export.failed, {
        duration: 3000,
        position: 'top-center',
      });
    } finally {
      setExportingId(null);
    }
  };

  const categories: { id: ExportCategory; icon: LucideIcon; label: string }[] = [
    { id: 'Code', icon: Code2, label: t.export.categories.code },
    { id: 'Image', icon: ImageIcon, label: t.export.categories.image },
    { id: 'File', icon: FileText, label: t.export.categories.file },
  ];

  return (
    <>
      {/* Toast Container with custom configuration */}
      <Toaster
        position="top-center"
        toastOptions={{
          duration: 3000,
          style: {
            background: '#fff',
            color: '#1f2937',
            fontSize: '14px',
            fontWeight: '500',
            borderRadius: '12px',
            boxShadow: '0 10px 40px rgba(59, 130, 246, 0.15), 0 2px 8px rgba(59, 130, 246, 0.1)',
            maxWidth: '420px',
          },
          success: {
            iconTheme: {
              primary: '#10b981',
              secondary: '#ffffff',
            },
            style: {
              border: '1px solid #d1fae5',
            },
          },
          error: {
            iconTheme: {
              primary: '#3b82f6',
              secondary: '#ffffff',
            },
            style: {
              border: '1px solid #dbeafe',
            },
          },
        }}
      />

      {/* Backdrop */}
      {isOpen && (
        <div
          className="absolute inset-0 bg-black/20 backdrop-blur-[1px] z-40 transition-opacity"
          onClick={onClose}
        />
      )}

      {/* Sidebar Panel */}
      <div
        className={`
            absolute top-0 right-0 bottom-0 w-80 bg-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out border-l border-gray-100 flex flex-col
            ${isOpen ? 'translate-x-0' : 'translate-x-full'}
        `}
      >
        <div className="flex items-center justify-between px-6 py-5 border-b border-gray-100 shrink-0">
          <h2 className="text-lg font-bold text-gray-900">{t.export.title}</h2>
          <button onClick={onClose} className="p-2 hover:bg-gray-100 rounded-full transition-colors">
            <X size={20} className="text-gray-500" />
          </button>
        </div>

        <div className="flex-1 overflow-y-auto p-6 space-y-8">
          {categories.map((category) => (
            <div key={category.id} className="space-y-3">
              <div className="flex items-center gap-2 text-gray-400 px-1">
                <category.icon size={16} />
                <span className="text-xs font-semibold uppercase tracking-wider">{category.label}</span>
              </div>

              <div className="space-y-2">
                {exportOptions
                  .filter(opt => opt.category === category.id)
                  .map(option => (
                    <button
                      key={option.id}
                      onClick={() => handleAction(option)}
                      className="w-full flex items-center justify-between p-3 bg-gray-50 hover:bg-blue-50 hover:text-blue-600 border border-transparent hover:border-blue-200 rounded-lg group transition-all text-left"
                    >
                      <span className="text-sm font-medium text-gray-700 group-hover:text-blue-700">
                        {option.label}
                      </span>

                      <div className="text-gray-400 group-hover:text-blue-600">
                        {exportingId === option.id ? (
                          <Loader2 size={16} className="animate-spin text-blue-500" />
                        ) : copiedId === option.id ? (
                          <Check size={16} className="text-green-500" />
                        ) : option.isDownload ? (
                          <Download size={16} />
                        ) : (
                          <Copy size={16} className="opacity-0 group-hover:opacity-100 transition-opacity" />
                        )}
                      </div>
                    </button>
                  ))
                }
              </div>
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

