/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useRef, useMemo } from 'react';
import CustomMediaInfoPanel from './components/CustomMediaInfoPanel';
import {
  FileManagerComponent,
  Inject,
  NavigationPane,
  DetailsView,
  Toolbar,
} from '@syncfusion/ej2-react-filemanager';
import { useAuth } from './useAuth';

const hostUrl = '/api/eventmedia/filemanager/'; // Dein Backend-Endpunkt für FileManager

const Media: React.FC = () => {
  const { user } = useAuth();
  const isSuperadmin = useMemo(() => user?.role === 'superadmin', [user]);
  // State für die angezeigten Dateidetails
  const [fileDetails] = useState<null | {
    name: string;
    size: number;
    type: string;
    dateModified: number;
    description?: string | null;
  }>(null);
  // Ansicht: 'LargeIcons', 'Details'
  const [viewMode, setViewMode] = useState<'LargeIcons' | 'Details'>('LargeIcons');
  const fileManagerRef = useRef<FileManagerComponent | null>(null);

  // Hilfsfunktion für Datum in Browser-Zeitzone
  function formatLocalDate(timestamp: number) {
    if (!timestamp) return '';
    const date = new Date(timestamp * 1000);
    return date.toLocaleString('de-DE'); // Zeigt lokale Zeit des Browsers
  }

  // Ansicht umschalten, ohne Remount
  React.useEffect(() => {
    if (fileManagerRef.current) {
      const element = fileManagerRef.current.element as HTMLElement & { ej2_instances?: unknown[] };
      if (element && element.ej2_instances && element.ej2_instances[0]) {
        // Typisiere Instanz als unknown, da kein offizieller Typ vorhanden
        const instanz = element.ej2_instances[0] as { view: string; dataBind: () => void };
        instanz.view = viewMode;
        instanz.dataBind();
      }
    }
  }, [viewMode]);

  type FileItem = { name: string; isFile: boolean };
  type ReadSuccessArgs = { action: string; result?: { files?: FileItem[] } };
  type FileOpenArgs = { fileDetails?: FileItem; cancel?: boolean };

  // Hide "converted" for non-superadmins after data load
  const handleSuccess = (args: ReadSuccessArgs) => {
    if (isSuperadmin) return;
    if (args && args.action === 'read' && args.result && Array.isArray(args.result.files)) {
      args.result.files = args.result.files.filter((f: FileItem) => !(f.name === 'converted' && !f.isFile));
    }
  };

  // Prevent opening the "converted" folder for non-superadmins
  const handleFileOpen = (args: FileOpenArgs) => {
    if (!isSuperadmin && args && args.fileDetails && args.fileDetails.name === 'converted' && !args.fileDetails.isFile) {
      args.cancel = true;
    }
  };

  return (
    <div>
      <h2 className="text-xl font-bold mb-4">Medien</h2>
      {/* Ansicht-Umschalter */}
      <div style={{ marginBottom: 12 }}>
        <button
          className={viewMode === 'LargeIcons' ? 'e-btn e-active' : 'e-btn'}
          onClick={() => setViewMode('LargeIcons')}
          style={{ marginRight: 8 }}
        >
          Icons
        </button>
        <button
          className={viewMode === 'Details' ? 'e-btn e-active' : 'e-btn'}
          onClick={() => setViewMode('Details')}
        >
          Details
        </button>
      </div>
      {/* Debug-Ausgabe entfernt, da ReactNode erwartet wird */}
      <FileManagerComponent
        ref={fileManagerRef}
        cssClass="e-bigger media-icons-xl"
        success={handleSuccess}
        fileOpen={handleFileOpen}
        ajaxSettings={{
          url: hostUrl + 'operations',
          getImageUrl: hostUrl + 'get-image',
          uploadUrl: hostUrl + 'upload',
          downloadUrl: hostUrl + 'download',
        }}
        // Increase upload settings: default maxFileSize for Syncfusion FileManager is ~30_000_000 (30 MB).
        // Set `maxFileSize` in bytes and `allowedExtensions` for video types you want to accept.
        // We disable autoUpload so we can validate duration client-side before sending.
        uploadSettings={{
         maxFileSize: 1.5 * 1024 * 1024 * 1024, // 1.5 GB - enough for 10min Full HD video at high bitrate
         allowedExtensions: '.pdf,.ppt,.pptx,.odp,.mp4,.webm,.ogg,.mov,.mkv,.avi,.wmv,.flv,.mpg,.mpeg,.jpg,.jpeg,.png,.gif,.bmp,.tiff,.svg',
          autoUpload: false,
         minFileSize: 0, // Allow all file sizes (no minimum)
          // chunkSize can be added later once server supports chunk assembly
        }}
        // Validate video duration (max 10 minutes) before starting upload.
        created={() => {
          try {
            const el = fileManagerRef.current?.element as any;
            const inst = el && el.ej2_instances && el.ej2_instances[0];
            const maxSeconds = 10 * 60; // 10 minutes
        if (inst && inst.uploadObj) {
              // Override the selected handler to validate files before upload
              const originalSelected = inst.uploadObj.selected;
              inst.uploadObj.selected = async (args: any) => {
                const filesData = args && (args.filesData || args.files) ? (args.filesData || args.files) : [];
                const tooLong: string[] = [];
                // Helper to get native File object
                const getRawFile = (fd: any) => fd && (fd.rawFile || fd.file || fd) as File;

                const checks = Array.from(filesData).map((fd: any) => {
                  const file = getRawFile(fd);
                  if (!file) return Promise.resolve(true);
                  // Only check video MIME types or common extensions
                  if (!file.type.startsWith('video') && !/\.(mp4|webm|ogg|mov|mkv)$/i.test(file.name)) {
                    return Promise.resolve(true);
                  }
                  return new Promise<boolean>((resolve) => {
                    const url = URL.createObjectURL(file);
                    const video = document.createElement('video');
                    video.preload = 'metadata';
                    video.src = url;
                    const clean = () => {
                      try { URL.revokeObjectURL(url); } catch { /* noop */ }
                    };
                    video.onloadedmetadata = function () {
                      clean();
                      if (video.duration && video.duration <= maxSeconds) {
                        resolve(true);
                      } else {
                        tooLong.push(`${file.name} (${Math.round(video.duration||0)}s)`);
                        resolve(false);
                      }
                    };
                    video.onerror = function () {
                      clean();
                      // If metadata can't be read, allow upload and let server verify
                      resolve(true);
                    };
                  });
                });

                const results = await Promise.all(checks);
                const allOk = results.every(Boolean);
                if (!allOk) {
                  // Cancel the automatic upload and show error to user
                  args.cancel = true;
                  const msg = `Upload blocked: the following videos exceed ${maxSeconds} seconds:\n` + tooLong.join('\n');
                  // Use alert for now; replace with project's toast system if available
                  alert(msg);
                  return;
                }
                // All files OK — proceed with original selected handler if present,
                // otherwise start upload programmatically
                if (typeof originalSelected === 'function') {
                  try { originalSelected.call(inst.uploadObj, args); } catch { /* noop */ }
                }
                // If autoUpload is false we need to start upload manually
                try {
                  inst.uploadObj.upload(args && (args.filesData || args.files));
                } catch { /* ignore — uploader may handle starting itself */ }
              };
            }
          } catch (e) {
            // Non-fatal: if we can't hook uploader, uploads will behave normally
            console.error('Could not attach video-duration hook to uploader', e);
          }
        }}
        toolbarSettings={{
          items: [
            'NewFolder',
            'Upload',
            'Download',
            'Rename',
            'Delete',
            'SortBy',
            'Refresh',
            'Details',
          ],
        }}
        contextMenuSettings={{
          file: ['Open', '|', 'Download', '|', 'Rename', 'Delete', '|', 'Details'],
          folder: ['Open', '|', 'Rename', 'Delete', '|', 'Details'],
          layout: ['SortBy', 'Refresh', '|', 'View', 'Details'],
        }}
        allowMultiSelection={false}
        view={viewMode}
        detailsViewSettings={{
          columns: [
            { field: 'name', headerText: 'Name', minWidth: '120', width: '200' },
            { field: 'size', headerText: 'Größe', minWidth: '80', width: '100' },
            {
              field: 'dateModified',
              headerText: 'Upload-Datum',
              minWidth: '120',
              width: '180',
              template: (data: { dateModified: number }) => formatLocalDate(data.dateModified),
            },
            { field: 'type', headerText: 'Typ', minWidth: '80', width: '100' },
          ],
        }}
        menuClick={() => {}}
      >
        <Inject services={[NavigationPane, DetailsView, Toolbar]} />
      </FileManagerComponent>
      {/* Details-Panel anzeigen, wenn Details verfügbar sind */}
      {fileDetails && <CustomMediaInfoPanel {...fileDetails} />}
    </div>
  );
};

export default Media;
