/**
 * FilesPage
 * 
 * Page for file management using FormGeneratorTable.
 * Follows the pattern established in AdminUsersPage/WorkflowsPage.
 */

import React, { useState, useMemo, useEffect, useRef } from 'react';
import { useUserFiles, useFileOperations } from '../../hooks/useFiles';
import { FormGeneratorTable } from '../../components/FormGenerator/FormGeneratorTable';
import { FormGeneratorForm } from '../../components/FormGenerator/FormGeneratorForm';
import { FaSync, FaFolder, FaUpload, FaDownload, FaEye } from 'react-icons/fa';
import { useToast } from '../../contexts/ToastContext';
import styles from '../admin/Admin.module.css';

interface UserFile {
  id: string;
  fileName: string;
  mimeType?: string;
  fileSize?: number;
  [key: string]: any;
}

export const FilesPage: React.FC = () => {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const { showSuccess, showError } = useToast();
  
  // Data hook
  const {
    data: files,
    attributes,
    permissions,
    pagination,
    loading,
    error,
    refetch,
    fetchFileById,
    updateFileOptimistically,
  } = useUserFiles();
  
  // Operations hook
  const {
    handleFileDownload,
    handleFileDelete,
    handleFileDeleteMultiple,
    handleFileUpload,
    handleFileUpdate,
    handleFilePreview,
    handleInlineUpdate,
    deletingFiles,
    downloadingFiles,
    uploadingFile,
    previewingFiles,
  } = useFileOperations();

  const [editingFile, setEditingFile] = useState<UserFile | null>(null);

  // Initial fetch
  useEffect(() => {
    refetch();
  }, []);

  // Generate columns from attributes - hide internal fields
  const columns = useMemo(() => {
    const hiddenColumns = ['id', 'mandateId', 'featureInstanceId', 'fileHash'];

    const cols = (attributes || [])
      .filter(attr => !hiddenColumns.includes(attr.name))
      .map(attr => ({
        key: attr.name,
        label: attr.label || attr.name,
        type: attr.type as any,
        sortable: attr.sortable !== false,
        filterable: attr.filterable !== false,
        searchable: attr.searchable !== false,
        width: attr.width || 150,
        minWidth: attr.minWidth || 100,
        maxWidth: attr.maxWidth || 400,
      }));

    // Add _createdBy column with FK resolution to show username
    cols.push({
      key: '_createdBy',
      label: 'Created By',
      type: 'text' as any,
      sortable: true,
      filterable: false,
      searchable: false,
      width: 150,
      minWidth: 100,
      maxWidth: 250,
      fkSource: '/api/users/',
      fkDisplayField: 'username',
    });

    return cols;
  }, [attributes]);

  // Check permissions
  const canCreate = permissions?.create !== 'n';
  const canUpdate = permissions?.update !== 'n';
  const canDelete = permissions?.delete !== 'n';

  // Handle edit click
  const handleEditClick = async (file: UserFile) => {
    const fullFile = await fetchFileById(file.id);
    if (fullFile) {
      setEditingFile(fullFile as UserFile);
    }
  };

  // Handle edit submit
  const handleEditSubmit = async (data: Partial<UserFile>) => {
    if (!editingFile) return;
    const result = await handleFileUpdate(editingFile.id, {
      fileName: data.fileName || editingFile.fileName
    }, editingFile);
    if (result.success) {
      setEditingFile(null);
      refetch();
    }
  };

  // Handle delete single file (confirmation handled by DeleteActionButton)
  const handleDelete = async (file: UserFile) => {
    const success = await handleFileDelete(file.id);
    if (success) {
      refetch();
    }
  };

  // Handle delete multiple files (confirmation handled by FormGenerator)
  const handleDeleteMultiple = async (filesToDelete: UserFile[]) => {
    const ids = filesToDelete.map(f => f.id);
    const success = await handleFileDeleteMultiple(ids);
    if (success) {
      refetch();
    }
  };

  // Handle download
  const handleDownload = async (file: UserFile) => {
    await handleFileDownload(file.id, file.fileName);
  };

  // Handle preview
  const handlePreview = async (file: UserFile) => {
    const result = await handleFilePreview(file.id, file.fileName, file.mimeType);
    if (result.success && result.previewUrl) {
      window.open(result.previewUrl, '_blank');
    }
  };

  // Handle upload click
  const handleUploadClick = () => {
    fileInputRef.current?.click();
  };

  // Handle file selection
  const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = e.target.files;
    if (selectedFiles && selectedFiles.length > 0) {
      let successCount = 0;
      let errorCount = 0;
      
      for (const file of Array.from(selectedFiles)) {
        const result = await handleFileUpload(file);
        if (result?.success) {
          successCount++;
        } else {
          errorCount++;
        }
      }
      
      // Reset input first
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
      
      // Refresh table to show new files
      await refetch();
      
      // Show feedback
      if (successCount > 0) {
        showSuccess(
          'Upload erfolgreich',
          `${successCount} Datei(en) hochgeladen${errorCount > 0 ? `, ${errorCount} fehlgeschlagen` : ''}`
        );
      } else if (errorCount > 0) {
        showError('Upload fehlgeschlagen', `${errorCount} Datei(en) konnten nicht hochgeladen werden`);
      }
    }
  };

  // Form attributes for edit modal
  const formAttributes = useMemo(() => {
    const excludedFields = ['id', 'mandateId', 'fileHash', '_createdBy', '_createdAt', '_modifiedAt', 'creationDate', 'source'];
    return (attributes || [])
      .filter(attr => !excludedFields.includes(attr.name));
  }, [attributes]);

  if (error) {
    return (
      <div className={styles.adminPage}>
        <div className={styles.errorContainer}>
          <span className={styles.errorIcon}>⚠️</span>
          <p className={styles.errorMessage}>Fehler beim Laden der Dateien: {error}</p>
          <button className={styles.secondaryButton} onClick={() => refetch()}>
            <FaSync /> Erneut versuchen
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className={styles.adminPage}>
      {/* Hidden file input */}
      <input
        ref={fileInputRef}
        type="file"
        multiple
        style={{ display: 'none' }}
        onChange={handleFileSelect}
      />

      <div className={styles.pageHeader}>
        <div>
          <h1 className={styles.pageTitle}>Dateien</h1>
          <p className={styles.pageSubtitle}>Dateiverwaltung</p>
        </div>
        <div className={styles.headerActions}>
          <button 
            className={styles.secondaryButton} 
            onClick={() => refetch()}
            disabled={loading}
          >
            <FaSync className={loading ? 'spinning' : ''} /> Aktualisieren
          </button>
          {canCreate && (
            <button 
              className={styles.primaryButton}
              onClick={handleUploadClick}
              disabled={uploadingFile}
            >
              <FaUpload /> {uploadingFile ? 'Uploading...' : 'Datei hochladen'}
            </button>
          )}
        </div>
      </div>

      <div className={styles.tableContainer}>
        {loading && (!files || files.length === 0) ? (
          <div className={styles.loadingContainer}>
            <div className={styles.spinner} />
            <span>Lade Dateien...</span>
          </div>
        ) : !files || files.length === 0 ? (
          <div className={styles.emptyState}>
            <FaFolder className={styles.emptyIcon} />
            <h3 className={styles.emptyTitle}>Keine Dateien vorhanden</h3>
            <p className={styles.emptyDescription}>
              Laden Sie eine Datei hoch, um loszulegen.
            </p>
            {canCreate && (
              <button 
                className={styles.primaryButton}
                onClick={handleUploadClick}
                disabled={uploadingFile}
              >
                <FaUpload /> Erste Datei hochladen
              </button>
            )}
          </div>
        ) : (
          <FormGeneratorTable
            data={files}
            columns={columns}
            apiEndpoint="/api/files/list"
            loading={loading}
            pagination={true}
            pageSize={25}
            searchable={true}
            filterable={true}
            sortable={true}
            selectable={true}
            actionButtons={[
              ...(canUpdate ? [{
                type: 'edit' as const,
                onAction: handleEditClick,
                title: 'Bearbeiten',
              }] : []),
              ...(canDelete ? [{
                type: 'delete' as const,
                title: 'Löschen',
                loading: (row: UserFile) => deletingFiles.has(row.id),
              }] : []),
            ]}
            customActions={[
              {
                id: 'download',
                icon: <FaDownload />,
                onClick: handleDownload,
                title: 'Herunterladen',
                loading: (row: UserFile) => downloadingFiles.has(row.id),
              },
              {
                id: 'preview',
                icon: <FaEye />,
                onClick: handlePreview,
                title: 'Vorschau',
                loading: (row: UserFile) => previewingFiles.has(row.id),
              },
            ]}
            onDelete={handleDelete}
            onDeleteMultiple={handleDeleteMultiple}
            hookData={{
              refetch,
              permissions,
              pagination,
              handleDelete: handleFileDelete,
              handleInlineUpdate,
              updateOptimistically: updateFileOptimistically,
            }}
            emptyMessage="Keine Dateien gefunden"
          />
        )}
      </div>

      {/* Edit Modal */}
      {editingFile && (
        <div className={styles.modalOverlay} onClick={() => setEditingFile(null)}>
          <div className={styles.modal} onClick={e => e.stopPropagation()}>
            <div className={styles.modalHeader}>
              <h2 className={styles.modalTitle}>Datei bearbeiten</h2>
              <button 
                className={styles.modalClose}
                onClick={() => setEditingFile(null)}
              >
                ✕
              </button>
            </div>
            <div className={styles.modalContent}>
              {formAttributes.length === 0 ? (
                <div className={styles.loadingContainer}>
                  <div className={styles.spinner} />
                  <span>Lade Formular...</span>
                </div>
              ) : (
                <FormGeneratorForm
                  attributes={formAttributes}
                  data={editingFile}
                  mode="edit"
                  onSubmit={handleEditSubmit}
                  onCancel={() => setEditingFile(null)}
                  submitButtonText="Speichern"
                  cancelButtonText="Abbrechen"
                />
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default FilesPage;
