import React, { useState } from 'react';
import { MdModeEdit } from 'react-icons/md';
import { useLanguage } from '../../../../contexts/LanguageContext';
import { Popup, EditForm } from '../../../Popup';
import styles from '../ActionButton.module.css';

export interface EditActionButtonProps<T = any> {
  row: T;
  onEdit?: (row: T) => void;
  disabled?: boolean | { disabled: boolean; message?: string };
  loading?: boolean;
  className?: string;
  title?: string;
  isEditing?: boolean;
  hookData: any; // REQUIRED: Contains all hook data including operations
  // Field mappings
  idField?: string; // Field name for the unique identifier
  nameField?: string; // Field name for display name
  typeField?: string; // Field name for type/mime type
  operationName?: string; // Name of the operation function in hookData
  loadingStateName?: string; // Name of the loading state in hookData
  // Edit configuration
  editFields?: Array<{
    key: string;
    label: string;
    type: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'readonly';
    editable?: boolean;
    required?: boolean;
    validator?: (value: any) => string | null;
  }>;
}

export function EditActionButton<T = any>({
  row,
  onEdit,
  disabled = false,
  loading = false,
  className = '',
  title,
  isEditing = false,
  hookData,
  idField = 'id',
  nameField = 'name',
  typeField = 'type',
  operationName = 'handleFileUpdate',
  loadingStateName = 'editingFiles',
  editFields = [
    {
      key: 'file_name',
      label: 'Filename',
      type: 'string',
      editable: true,
      required: true,
      validator: (value: string) => {
        if (!value || value.trim() === '') {
          return 'Filename cannot be empty';
        }
        if (value.includes('/') || value.includes('\\')) {
          return 'Filename cannot contain / or \\ characters';
        }
        return null;
      }
    }
  ]
}: EditActionButtonProps<T>) {
  const { t } = useLanguage();
  const [internalLoading, setInternalLoading] = useState(false);
  const [isPopupOpen, setIsPopupOpen] = useState(false);
  const [editData, setEditData] = useState<T | null>(null);
  
  // Extract disabled state and tooltip message
  const isDisabled = typeof disabled === 'boolean' ? disabled : disabled?.disabled || false;
  const disabledMessage = typeof disabled === 'object' ? disabled?.message : undefined;
  
  // Debug logging for disabled state
  if (import.meta.env.DEV) {
    console.log('EditActionButton disabled prop:', disabled);
    console.log('EditActionButton isDisabled:', isDisabled);
    console.log('EditActionButton disabledMessage:', disabledMessage);
    console.log('EditActionButton row:', row);
  }
  
  // Validate that hookData is provided
  if (!hookData) {
    throw new Error('EditActionButton requires hookData to be provided');
  }

  const handleClick = async (e: React.MouseEvent) => {
    e.stopPropagation();
    if (!isDisabled && !loading && !isEditing && !internalLoading) {
      setInternalLoading(true);
      try {
        // Debug logging to see what data we're working with
        if (import.meta.env.DEV) {
          console.log('EditActionButton received row:', row);
          console.log('Field mappings:', { idField, nameField, typeField });
          console.log('Extracted values:', {
            id: (row as any)[idField],
            name: (row as any)[nameField],
            type: (row as any)[typeField]
          });
        }
        
        // Call the onEdit callback if provided
        if (onEdit) {
          await onEdit(row);
        }
        
        // Set up edit data and open popup
        setEditData(row);
        setIsPopupOpen(true);
      } finally {
        setInternalLoading(false);
      }
    }
  };

  const handleSave = async (updatedData: T) => {
    if (!editData) return;

    try {
      setInternalLoading(true);
      
      // Get the item ID from the row
      const itemId = (editData as any)[idField];
      
      // Extract the fields to update from the edit data
      const updateData: any = {};
      editFields.forEach(field => {
        if (field.editable !== false) {
          // Map frontend field names to API field names
          if (field.key === 'file_name') {
            updateData.fileName = (updatedData as any)[field.key];
          } else {
            updateData[field.key] = (updatedData as any)[field.key];
          }
        }
      });

      // Debug logging
      if (import.meta.env.DEV) {
        console.log('EditActionButton - Update data:', {
          itemId,
          updateData,
          originalData: editData,
          updatedData,
          editFields: editFields.map(f => ({ key: f.key, value: (updatedData as any)[f.key] })),
          updateDataKeys: Object.keys(updateData),
          updateDataValues: Object.values(updateData)
        });
      }

      // Validate required operation exists
      if (!hookData[operationName]) {
        throw new Error(`EditActionButton requires hookData.${operationName} to be defined`);
      }
      if (!hookData.refetch) {
        throw new Error('EditActionButton requires hookData.refetch to be defined');
      }

      // Use hookData operation to update
      const result = await hookData[operationName](itemId, updateData, editData);
      const success = result?.success || result === true;

      if (success) {
        // Close popup and reset state
        setIsPopupOpen(false);
        setEditData(null);
        
        // Trigger refetch to sync with backend
        await hookData.refetch();
      } else {
        console.error('Failed to update item:', itemId);
        // TODO: Show error message to user
      }
    } catch (error) {
      console.error('Failed to update item:', error);
      // TODO: Show error message to user
    } finally {
      setInternalLoading(false);
    }
  };

  const handleCancel = () => {
    setIsPopupOpen(false);
    setEditData(null);
  };

  const buttonTitle = title || t('files.action.edit', 'Edit');
  // Use hookData editing state if available, otherwise use passed isEditing
  const loadingState = hookData?.[loadingStateName];
  const actualIsEditing = loadingState?.has((row as any)[idField]) || isEditing;
  const isLoading = loading || actualIsEditing || internalLoading;

  // Determine the final button title (tooltip)
  const finalTitle = isDisabled && disabledMessage ? disabledMessage : buttonTitle;

  // Debug logging for button rendering
  if (import.meta.env.DEV) {
    console.log('EditActionButton rendering with:', {
      isDisabled,
      isLoading,
      finalTitle,
      className: `${styles.actionButton} ${styles.edit} ${isLoading ? styles.loading : ''} ${isDisabled ? styles.disabled : ''} ${className}`
    });
  }

  return (
    <>
      <button
        onClick={handleClick}
        className={`${styles.actionButton} ${styles.edit} ${isLoading ? styles.loading : ''} ${isDisabled ? styles.disabled : ''} ${className}`}
        title={finalTitle}
        disabled={isDisabled || isLoading}
      >
        <span className={styles.actionIcon}>
          {isLoading ? '⏳' : <MdModeEdit />}
        </span>
      </button>

      {/* Edit Popup */}
      <Popup
        isOpen={isPopupOpen}
        title={t('files.edit.title', 'Edit Item')}
        onClose={handleCancel}
        size="small"
        closable={true}
      >
        {editData && (
          <EditForm
            data={editData}
            fields={editFields.map(field => ({
              key: field.key,
              label: field.label,
              type: field.type,
              editable: field.editable ?? true,
              required: field.required ?? false,
              validator: field.validator
            }))}
            onSave={handleSave}
            onCancel={handleCancel}
            saveButtonText={t('common.save', 'Save')}
            cancelButtonText={t('common.cancel', 'Cancel')}
          />
        )}
      </Popup>
    </>
  );
}

export default EditActionButton;
