import { useCallback, useEffect, useState } from 'react';

import { IoIosDownload, IoIosCopy } from 'react-icons/io';

import { Popup, PopupAction } from '../UiComponents/Popup/Popup';
import { useLanguage } from '../../providers/language/LanguageContext';
import { useFileOperations } from '../../hooks/useFiles';
import {
  JsonRenderer,
  ImageRenderer,
  TextRenderer,
  PdfRenderer,
  HtmlRenderer,
  ApplicationRenderer,
  UnsupportedRenderer,
  LoadingRenderer,
  ErrorRenderer,
  WordRenderer,
  ExcelRenderer,
  isWordMimeType,
  isExcelMimeType,
} from './renderers';
import styles from './ContentPreview.module.css';

export interface ContentPreviewProps {
  isOpen: boolean;
  onClose: () => void;
  fileId: string;
  fileName: string;
  mimeType?: string;
}

export function ContentPreview({
  isOpen,
  onClose,
  fileId,
  fileName,
  mimeType,
}: ContentPreviewProps) {
  const { t } = useLanguage();
  const {
    handleFilePreview,
    handleFileDownload,
    previewingFiles,
    previewError,
    downloadingFiles,
  } = useFileOperations();

  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [blob, setBlob] = useState<Blob | null>(null);
  const [textContent, setTextContent] = useState<string | null>(null);
  const [resolvedMime, setResolvedMime] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [copySuccess, setCopySuccess] = useState(false);

  const cleanup = useCallback(() => {
    setPreviewUrl(prev => {
      if (prev) window.URL.revokeObjectURL(prev);
      return null;
    });
    setBlob(null);
    setTextContent(null);
    setResolvedMime(null);
  }, []);

  const loadPreview = useCallback(async () => {
    setError(null);
    cleanup();

    const result = await handleFilePreview(fileId, fileName, mimeType);
    if (!result.success) {
      setError(result.error || t('Vorschau konnte nicht geladen werden.'));
      return;
    }

    setPreviewUrl(result.previewUrl ?? null);
    setBlob(result.blob ?? null);
    setTextContent(result.textContent ?? null);
    setResolvedMime(result.mimeType ?? mimeType ?? null);
  }, [cleanup, fileId, fileName, handleFilePreview, mimeType, t]);

  useEffect(() => {
    if (!isOpen || !fileId) {
      cleanup();
      setError(null);
      return;
    }

    if (fileId === 'undefined' || fileId === 'null') {
      setError(t('Ungültige Datei-ID'));
      return;
    }
    if (!fileName || fileName === 'Unknown Item' || fileName === 'Unbekanntes Element') {
      setError(t('Dateiname nicht verfügbar'));
      return;
    }

    loadPreview();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, fileId, fileName]);

  useEffect(() => {
    return () => {
      if (previewUrl) window.URL.revokeObjectURL(previewUrl);
    };
  }, [previewUrl]);

  const effectiveMime = resolvedMime ?? mimeType;
  const isPreviewing = previewingFiles.has(fileId);
  const hasError = error || previewError;

  const handleCopyContent = async () => {
    if (!textContent) return;
    try {
      await navigator.clipboard.writeText(textContent);
      setCopySuccess(true);
      setTimeout(() => setCopySuccess(false), 2000);
    } catch (err) {
      console.error('Failed to copy content:', err);
    }
  };

  const handleDownloadFile = async () => {
    try {
      await handleFileDownload(fileId, fileName);
    } catch (err) {
      console.error('Failed to download file:', err);
    }
  };

  const actions: PopupAction[] = [
    ...(textContent
      ? [
          {
            label: copySuccess ? t('In die Zwischenablage kopiert') : '',
            icon: copySuccess ? '✓' : <IoIosCopy />,
            onClick: handleCopyContent,
            disabled: !textContent,
            variant: 'primary' as const,
          },
        ]
      : []),
    {
      label: '',
      icon: downloadingFiles.has(fileId) ? undefined : <IoIosDownload />,
      onClick: handleDownloadFile,
      disabled: downloadingFiles.has(fileId),
      loading: downloadingFiles.has(fileId),
      variant: 'success' as const,
    },
  ];

  const renderPreview = () => {
    if (isPreviewing) return <LoadingRenderer />;
    if (hasError) return <ErrorRenderer error={hasError} onRetry={loadPreview} />;
    if (!blob || !effectiveMime) return null;

    if (effectiveMime === 'application/json' && textContent) {
      return <JsonRenderer previewContent={textContent} fileName={fileName} />;
    }

    if (isWordMimeType(effectiveMime, fileName)) {
      return (
        <WordRenderer
          blob={blob}
          fileName={fileName}
          mimeType={effectiveMime}
          onError={msg => setError(msg)}
        />
      );
    }

    if (isExcelMimeType(effectiveMime, fileName)) {
      return (
        <ExcelRenderer
          blob={blob}
          fileName={fileName}
          onError={msg => setError(msg)}
        />
      );
    }

    const mimePrefix = effectiveMime.split('/')[0];

    switch (mimePrefix) {
      case 'image':
        if (!previewUrl) return null;
        return (
          <ImageRenderer
            previewUrl={previewUrl}
            fileName={fileName}
            onError={() => setError(t('Bildvorschau konnte nicht geladen werden'))}
          />
        );

      case 'text':
        if (effectiveMime === 'text/html' && previewUrl) {
          return (
            <HtmlRenderer
              previewUrl={previewUrl}
              fileName={fileName}
              onError={() => setError(t('HTML-Vorschau konnte nicht geladen werden'))}
            />
          );
        }
        return (
          <TextRenderer
            previewUrl={previewUrl ?? undefined}
            previewContent={textContent ?? undefined}
            fileName={fileName}
            mimeType={effectiveMime}
            onError={() => setError(t('Textvorschau konnte nicht geladen werden'))}
          />
        );

      case 'application':
        if (effectiveMime === 'application/pdf' && previewUrl) {
          return (
            <PdfRenderer
              previewUrl={previewUrl}
              fileName={fileName}
              onError={() => setError(t('PDF-Vorschau konnte nicht geladen werden'))}
            />
          );
        }
        if (effectiveMime === 'application/html' && previewUrl) {
          return (
            <HtmlRenderer
              previewUrl={previewUrl}
              fileName={fileName}
              onError={() => setError(t('HTML-Vorschau konnte nicht geladen werden'))}
            />
          );
        }
        return (
          <ApplicationRenderer
            previewUrl={previewUrl ?? ''}
            fileName={fileName}
            mimeType={effectiveMime}
            onError={() =>
              setError(t('Vorschau wird für dieses Format nicht unterstützt'))
            }
          />
        );

      default:
        return <UnsupportedRenderer previewUrl={previewUrl ?? ''} fileName={fileName} />;
    }
  };

  return (
    <Popup
      isOpen={isOpen}
      onClose={onClose}
      title={`${t('Dateivorschau')}: ${fileName}`}
      size="fullscreen"
      className={styles.contentPreviewPopup}
      actions={actions}
    >
      <div className={styles.previewContainer}>{renderPreview()}</div>
    </Popup>
  );
}

export default ContentPreview;
