/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useEffect } from 'react';
import {   mapManifestColumns, 
  getManifestColumnMapping, 
  updateManifestColumnMapping,
  ManifestColumnMappingData,
  ManifestColumnMappingResponse  } from '../../../../Api/ShipmentApi';

interface ManifestColumnMappingProps {
  shipmentId: number | string;
  onMappingSuccess?: (response: ManifestColumnMappingResponse) => void;
  onMappingError?: (error: string) => void;
}

// Common field mappings that are typically used
const COMMON_FIELDS = [
  'delybell_order_id',
  'receiver_name',
  'receiver_phone',
  'receiver_address',
  'receiver_city',
  'receiver_state',
  'receiver_country',
  'receiver_postal_code',
  'package_weight',
  'package_dimensions',
  'shipping_method',
  'tracking_number',
  'order_date',
  'delivery_date',
  'special_instructions',
  'customer_reference',
  'product_description',
  'quantity',
  'unit_price',
  'total_amount'
];

const ManifestColumnMapping: React.FC<ManifestColumnMappingProps> = ({
  shipmentId,
  onMappingSuccess,
  onMappingError
}) => {
  const [mappings, setMappings] = useState<{ [key: string]: number }>({});
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [message, setMessage] = useState<string>('');
  const [messageType, setMessageType] = useState<'success' | 'error' | 'info'>('info');
  const [availableFields, setAvailableFields] = useState<string[]>([]);

  useEffect(() => {
    loadExistingMapping();
    setAvailableFields(COMMON_FIELDS);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [shipmentId]);

  const loadExistingMapping = async () => {
    setIsLoading(true);
    try {
      const result = await getManifestColumnMapping(shipmentId);
      if (result.success && result.data) {
        // Convert array format to object format for easier editing
        const mappingObject: { [key: string]: number | any } = {};
        if (Array.isArray(result.data.manifest_columns)) {
          result.data.manifest_columns.forEach((mapping: any) => {
            const [fieldName, columnIndex] = Object.entries(mapping)[0];
            mappingObject[fieldName] = columnIndex;
          });
        }
        setMappings(mappingObject);
        setMessage('Existing mapping loaded successfully');
        setMessageType('success');
      } else {
        setMessage('No existing mapping found. Please create a new mapping.');
        setMessageType('info');
      }
    } catch (error: unknown) {
      setMessage('Failed to load existing mapping');
      setMessageType('error');
      onMappingError?.('Failed to load existing mapping');
    } finally {
      setIsLoading(false);
    }
  };

  const handleFieldChange = (fieldName: string, columnIndex: string) => {
    const index = parseInt(columnIndex);
    if (isNaN(index) || index < 0) {
      return;
    }

    setMappings(prev => ({
      ...prev,
      [fieldName]: index
    }));
  };

  const addNewField = () => {
    const newField = `field_${Object.keys(mappings).length + 1}`;
    setMappings(prev => ({
      ...prev,
      [newField]: 0
    }));
    setAvailableFields(prev => [...prev, newField]);
  };

  const removeField = (fieldName: string) => {
    setMappings(prev => {
      const newMappings = { ...prev };
      delete newMappings[fieldName];
      return newMappings;
    });
  };

  const saveMapping = async () => {
    if (Object.keys(mappings).length === 0) {
      setMessage('Please add at least one field mapping');
      setMessageType('error');
      return;
    }

    setIsSaving(true);
    try {
      // Convert object format to array format for API
      const mappingData: ManifestColumnMappingData = {
        shipment_id: shipmentId,
        manifest_columns: Object.entries(mappings).map(([fieldName, columnIndex]) => ({
          [fieldName]: columnIndex
        }))
      };

      const result = await mapManifestColumns(mappingData);

      if (result.success) {
        setMessage('Column mapping saved successfully!');
        setMessageType('success');
        onMappingSuccess?.(result);
      } else {
        setMessage(`Failed to save mapping: ${result.error}`);
        setMessageType('error');
        onMappingError?.(result.error || 'Failed to save mapping');
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
      setMessage(`Error: ${errorMessage}`);
      setMessageType('error');
      onMappingError?.(errorMessage);
    } finally {
      setIsSaving(false);
    }
  };

  const updateMapping = async () => {
    if (Object.keys(mappings).length === 0) {
      setMessage('Please add at least one field mapping');
      setMessageType('error');
      return;
    }

    setIsSaving(true);
    try {
      const mappingData: ManifestColumnMappingData = {
        shipment_id: shipmentId,
        manifest_columns: Object.entries(mappings).map(([fieldName, columnIndex]) => ({
          [fieldName]: columnIndex
        }))
      };

      const result = await updateManifestColumnMapping(mappingData);

      if (result.success) {
        setMessage('Column mapping updated successfully!');
        setMessageType('success');
        onMappingSuccess?.(result);
      } else {
        setMessage(`Failed to update mapping: ${result.error}`);
        setMessageType('error');
        onMappingError?.(result.error || 'Failed to update mapping');
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
      setMessage(`Error: ${errorMessage}`);
      setMessageType('error');
      onMappingError?.(errorMessage);
    } finally {
      setIsSaving(false);
    }
  };

  const resetMapping = () => {
    setMappings({});
    setMessage('Mapping reset. Please add new field mappings.');
    setMessageType('info');
  };

  const getMessageClass = () => {
    switch (messageType) {
      case 'success': return 'alert-success';
      case 'error': return 'alert-danger';
      case 'info': return 'alert-info';
      default: return 'alert-info';
    }
  };

  return (
    <div className="manifest-column-mapping">
      <div className="card">
        <div className="card-header">
          <h5 className="mb-0">
            <i className="fa fa-columns me-2" />
            Manifest Column Mapping
          </h5>
          <small className="text-muted">
            Map Excel columns to system fields for shipment {shipmentId}
          </small>
        </div>
        <div className="card-body">
          {/* Status Message */}
          {message && (
            <div className={`alert ${getMessageClass()} alert-dismissible fade show`}>
              {message}
              <button
                type="button"
                className="btn-close"
                onClick={() => setMessage('')}
              />
            </div>
          )}

          {/* Instructions */}
          <div className="alert alert-info mb-3">
            <i className="fa fa-info-circle me-2" />
            <strong>Instructions:</strong> Map each system field to the corresponding column index in your Excel file.
            Column indices start from 0 (first column = 0, second column = 1, etc.).
          </div>

          {/* Field Mappings */}
          <div className="mb-3">
            <div className="d-flex justify-content-between align-items-center mb-2">
              <h6 className="mb-0">Field Mappings</h6>
              <button
                className="btn btn-sm btn-outline-primary"
                onClick={addNewField}
                disabled={isLoading || isSaving}
              >
                <i className="fa fa-plus me-1" />
                Add Field
              </button>
            </div>

            {Object.keys(mappings).length === 0 ? (
              <div className="text-center py-4 text-muted">
                <i className="fa fa-columns fa-2x mb-2" />
                <p>No field mappings added yet.</p>
                <p>{`Click "Add Field" to start mapping your Excel columns.`}</p>
              </div>
            ) : (
              <div className="table-responsive">
                <table className="table table-bordered">
                  <thead className="table-light">
                    <tr>
                      <th>System Field</th>
                      <th>Excel Column Index</th>
                      <th>Actions</th>
                    </tr>
                  </thead>
                  <tbody>
                    {Object.entries(mappings).map(([fieldName, columnIndex]) => (
                      <tr key={fieldName}>
                        <td>
                          <select
                            className="form-select"
                            value={fieldName}
                            onChange={(e) => {
                              const newFieldName = e.target.value;
                              const newMappings = { ...mappings };
                              delete newMappings[fieldName];
                              newMappings[newFieldName] = columnIndex;
                              setMappings(newMappings);
                            }}
                            disabled={isLoading || isSaving}
                          >
                            {availableFields.map(field => (
                              <option key={field} value={field}>
                                {field.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
                              </option>
                            ))}
                          </select>
                        </td>
                        <td>
                          <input
                            type="number"
                            className="form-control"
                            min="0"
                            value={columnIndex}
                            onChange={(e) => handleFieldChange(fieldName, e.target.value)}
                            disabled={isLoading || isSaving}
                            placeholder="Column index (0, 1, 2...)"
                          />
                        </td>
                        <td>
                          <button
                            className="btn btn-sm btn-outline-danger"
                            onClick={() => removeField(fieldName)}
                            disabled={isLoading || isSaving}
                          >
                            <i className="fa fa-trash" />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>

          {/* Action Buttons */}
          <div className="d-flex gap-2">
            <button
              className="btn btn-primary"
              onClick={saveMapping}
              disabled={isLoading || isSaving || Object.keys(mappings).length === 0}
            >
              {isSaving ? (
                <>
                  <span className="spinner-border spinner-border-sm me-2" />
                  Saving...
                </>
              ) : (
                <>
                  <i className="fa fa-save me-2" />
                  Save Mapping
                </>
              )}
            </button>

            <button
              className="btn btn-secondary"
              onClick={updateMapping}
              disabled={isLoading || isSaving || Object.keys(mappings).length === 0}
            >
              <i className="fa fa-edit me-2" />
              Update Mapping
            </button>

            <button
              className="btn btn-outline-secondary"
              onClick={resetMapping}
              disabled={isLoading || isSaving}
            >
              <i className="fa fa-refresh me-2" />
              Reset
            </button>

            <button
              className="btn btn-outline-info"
              onClick={loadExistingMapping}
              disabled={isLoading || isSaving}
            >
              <i className="fa fa-sync me-2" />
              Reload
            </button>
          </div>

          {/* JSON Preview */}
          {Object.keys(mappings).length > 0 && (
            <div className="mt-3">
              <h6>API Payload Preview:</h6>
              <pre className="bg-light p-3 rounded">
                <code>
                  {JSON.stringify({
                    shipment_id: shipmentId,
                    manifest_columns: Object.entries(mappings).map(([fieldName, columnIndex]) => ({
                      [fieldName]: columnIndex
                    }))
                  }, null, 2)}
                </code>
              </pre>
            </div>
          )}
        </div>
      </div>

      <style jsx>{`
        .manifest-column-mapping {
          max-width: 800px;
          margin: 0 auto;
        }
        
        .table th {
          background-color: #f8f9fa;
          border-color: #dee2e6;
        }
        
        .form-select, .form-control {
          border-radius: 0.375rem;
        }
        
        .btn {
          border-radius: 0.375rem;
        }
        
        pre {
          font-size: 0.875rem;
          max-height: 300px;
          overflow-y: auto;
        }
      `}</style>
    </div>
  );
};

export default ManifestColumnMapping;
