import React, { useState, useMemo } from 'react';
import { CreateButtonProps } from '../ButtonTypes';
import Button from '../Button';
import { Popup } from '../../Popup';
import { FormGeneratorForm, AttributeDefinition } from '../../../FormGenerator/FormGeneratorForm';
import { useLanguage } from '../../../../providers/language/LanguageContext';
import { TextField } from '../../TextField';
import { PekProvider } from '../../../../contexts/PekContext';
import { MapView } from '../../MapView';
import { usePekContext } from '../../../../contexts/PekContext';
import { FaLocationArrow, FaTimes } from 'react-icons/fa';
import { IoMdSend } from 'react-icons/io';
import styles from './CreateButton.module.css';

// Step 2 component for parcel selection (must be inside PekProvider)
const Step2Content: React.FC<{
  onNext: (data: any) => void;
  onBack: () => void;
  addressData: {
    street: string;
    postalCode: string;
    city: string;
  };
  onAddressChange: (field: string, value: string) => void;
}> = ({ onNext, onBack, addressData, onAddressChange }) => {
  const { t } = useLanguage();
  const { 
    selectedParcels, 
    searchParcel, 
    useCurrentLocation, 
    isGettingLocation, 
    isSearchingParcel, 
    setAdresse,
    mapCenter,
    mapZoomBounds,
    parcelGeometries,
    handleMapClick,
    handleParcelClick,
    removeParcel,
    setIsPanelOpen
  } = usePekContext();
  const [step2Errors, setStep2Errors] = useState<Record<string, string>>({});

  // Prevent panel from opening when parcel is clicked
  React.useEffect(() => {
    setIsPanelOpen(false);
  }, [selectedParcels, setIsPanelOpen]);

  // Build location string from address fields
  const buildLocationString = () => {
    const parts = [];
    if (addressData.street.trim()) parts.push(addressData.street.trim());
    if (addressData.postalCode.trim()) parts.push(addressData.postalCode.trim());
    if (addressData.city.trim()) parts.push(addressData.city.trim());
    return parts.join(', ');
  };

  const handleSearch = async () => {
    const locationString = buildLocationString();
    if (locationString.trim()) {
      // Update the adresse field in context for consistency
      setAdresse(locationString);
      await searchParcel(locationString.trim(), true);
    }
  };

  const handleUseCurrentLocation = async () => {
    await useCurrentLocation();
  };

  const handleNext = () => {
    const newErrors: Record<string, string> = {};
    
    if (!addressData.street.trim()) {
      newErrors.street = t('formgen.form.required', 'Strasse und Hausnummer ist erforderlich');
    }
    if (!addressData.postalCode.trim()) {
      newErrors.postalCode = t('formgen.form.required', 'Postleitzahl ist erforderlich');
    }
    if (!addressData.city.trim()) {
      newErrors.city = t('formgen.form.required', 'Stadt ist erforderlich');
    }
    if (!selectedParcels || selectedParcels.length === 0) {
      newErrors.parcel = t('formgen.form.required', 'Bitte wählen Sie mindestens eine Parzelle aus');
    }

    setStep2Errors(newErrors);
    
    if (Object.keys(newErrors).length === 0) {
      onNext({
        address: addressData,
        parzellen: selectedParcels
      });
    }
  };

  return (
    <div className={styles.step2Container}>
      <div className={styles.stepIndicator}>
        <span className={styles.stepNumber}>2</span>
        <span className={styles.stepLabel}>Parzelle hinzufügen</span>
      </div>
      
      <div className={styles.addressFields}>
        <TextField
          value={addressData.street}
          onChange={(value) => onAddressChange('street', value)}
          label="Strasse und Hausnummer"
          placeholder="z.B. Bundesplatz 3"
          required
          error={step2Errors.street}
          size="md"
          type="text"
          onKeyDown={(e) => {
            if (e.key === 'Enter') {
              e.preventDefault();
              handleSearch();
            }
          }}
        />
        
        <div className={styles.addressRow}>
          <TextField
            value={addressData.postalCode}
            onChange={(value) => onAddressChange('postalCode', value)}
            label="Postleitzahl"
            placeholder="z.B. 3000"
            required
            error={step2Errors.postalCode}
            size="md"
            type="text"
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
                handleSearch();
              }
            }}
          />
          
          <TextField
            value={addressData.city}
            onChange={(value) => onAddressChange('city', value)}
            label="Stadt"
            placeholder="z.B. Bern"
            required
            error={step2Errors.city}
            size="md"
            type="text"
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
                handleSearch();
              }
            }}
          />
        </div>
      </div>

      {/* Search buttons */}
      <div className={styles.searchButtons}>
        <Button
          variant="primary"
          size="md"
          icon={IoMdSend}
          onClick={handleSearch}
          disabled={!buildLocationString().trim() || isGettingLocation || isSearchingParcel}
          loading={isSearchingParcel}
        >
          Suchen
        </Button>
        <Button
          variant="secondary"
          size="md"
          icon={FaLocationArrow}
          onClick={handleUseCurrentLocation}
          disabled={isGettingLocation || isSearchingParcel}
          loading={isGettingLocation}
        >
          Meine Position
        </Button>
      </div>

      <div className={styles.mapSection}>
        <div className={styles.mapContainer}>
          <MapView
            parcels={parcelGeometries}
            center={mapCenter || undefined}
            zoomBounds={mapZoomBounds || undefined}
            onMapClick={handleMapClick}
            onParcelClick={handleParcelClick}
            height="400px"
            emptyMessage="Klicken Sie auf die Karte, um einen Standort auszuwählen, oder suchen Sie nach einer Adresse oben."
          />
        </div>
        
        {/* Selected parcels list displayed below map */}
        {selectedParcels && selectedParcels.length > 0 && (
          <div className={styles.parcelInfo}>
            <h3 className={styles.parcelInfoTitle}>Ausgewählte Parzellen ({selectedParcels.length})</h3>
            <div className={styles.selectedParcelsList}>
              {selectedParcels.map((selectedParcel, index) => (
                <div key={selectedParcel.parcel.id || index} className={styles.selectedParcelCard}>
                  <div className={styles.selectedParcelHeader}>
                    <h4 className={styles.selectedParcelTitle}>
                      Parzelle {index + 1}: {selectedParcel.parcel.number || selectedParcel.parcel.id || 'Unbekannt'}
                    </h4>
                    <button
                      className={styles.removeParcelButton}
                      onClick={() => removeParcel(selectedParcel.parcel.id)}
                      title="Parzelle entfernen"
                    >
                      <FaTimes />
                    </button>
                  </div>
                  <div className={styles.parcelInfoGrid}>
                    {selectedParcel.parcel.id && (
                      <div className={styles.parcelInfoItem}>
                        <span className={styles.parcelInfoLabel}>ID:</span>
                        <span className={styles.parcelInfoValue}>{selectedParcel.parcel.id}</span>
                      </div>
                    )}
                    {selectedParcel.parcel.number && (
                      <div className={styles.parcelInfoItem}>
                        <span className={styles.parcelInfoLabel}>Nummer:</span>
                        <span className={styles.parcelInfoValue}>{selectedParcel.parcel.number}</span>
                      </div>
                    )}
                    {selectedParcel.parcel.egrid && (
                      <div className={styles.parcelInfoItem}>
                        <span className={styles.parcelInfoLabel}>EGRID:</span>
                        <span className={styles.parcelInfoValue}>{selectedParcel.parcel.egrid}</span>
                      </div>
                    )}
                    {selectedParcel.parcel.address && (
                      <div className={styles.parcelInfoItem}>
                        <span className={styles.parcelInfoLabel}>Adresse:</span>
                        <span className={styles.parcelInfoValue}>{selectedParcel.parcel.address}</span>
                      </div>
                    )}
                    {selectedParcel.parcel.area_m2 && (
                      <div className={styles.parcelInfoItem}>
                        <span className={styles.parcelInfoLabel}>Fläche (m²):</span>
                        <span className={styles.parcelInfoValue}>{selectedParcel.parcel.area_m2}</span>
                      </div>
                    )}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
        
        {step2Errors.parcel && (
          <span className={styles.errorText}>{step2Errors.parcel}</span>
        )}
      </div>

      <div className={styles.buttonGroup}>
        <Button
          variant="secondary"
          size="md"
          onClick={onBack}
        >
          {t('common.back', 'Zurück')}
        </Button>
        <Button
          variant="primary"
          size="md"
          onClick={handleNext}
        >
          {t('common.finish', 'Abschließen')}
        </Button>
      </div>
    </div>
  );
};

const CreateButton: React.FC<CreateButtonProps> = ({
  onCreate,
  fields,
  popupTitle = 'Create New Item',
  popupSize = 'medium',
  disabled = false,
  loading = false,
  className = '',
  children,
  icon,
  iconPosition = 'left',
  variant = 'primary',
  size = 'md',
  onSuccess,
  onError,
  multiStep = false,
  ...props
}) => {
  const { t } = useLanguage();
  const [isCreating, setIsCreating] = useState(false);
  const [isPopupOpen, setIsPopupOpen] = useState(false);
  const [currentStep, setCurrentStep] = useState<1 | 2>(1);
  const [step1Data, setStep1Data] = useState<any>({});
  const [addressData, setAddressData] = useState({
    street: '',
    postalCode: '',
    city: ''
  });

  // Filter fields for multi-step: Step 1 only shows "label" field
  const step1Fields = useMemo(() => {
    if (multiStep) {
      return fields.filter(field => field.key === 'label');
    }
    return fields;
  }, [fields, multiStep]);

  // Convert CreateButtonFieldConfig to AttributeDefinition format
  const attributes: AttributeDefinition[] = useMemo(() => {
    const fieldsToUse = multiStep ? step1Fields : fields;
    return fieldsToUse.map(field => {
      // Convert options to AttributeOption[] format
      let options: AttributeDefinition['options'] = undefined;
      
      if (field.options) {
        // If options is an array of strings, convert to AttributeOption format
        if (Array.isArray(field.options)) {
          options = field.options.map(opt => {
            if (typeof opt === 'string') {
              return { value: opt, label: opt };
            }
            // Already in {value, label} format
            return opt;
          });
        }
      } else if (field.optionsReference) {
        // Use optionsReference as string (will be fetched from API)
        options = field.optionsReference;
      }
      
      // Map field types to FormGeneratorForm attribute types
      let attributeType: AttributeDefinition['type'] = 'text';
      if (field.type === 'boolean') {
        attributeType = 'checkbox';
      } else if (field.type === 'enum') {
        attributeType = 'select';
      } else if (field.type === 'multiselect') {
        attributeType = 'multiselect';
      } else if (field.type === 'email') {
        attributeType = 'email';
      } else if (field.type === 'date') {
        attributeType = 'date';
      } else if (field.type === 'textarea') {
        attributeType = 'textarea';
      } else if (field.type === 'readonly') {
        attributeType = 'readonly';
      } else if (field.type === 'string') {
        // Check if it's a password field by key name
        attributeType = field.key.toLowerCase().includes('password') ? 'password' : 'text';
      }
      
      return {
        name: field.key,
        label: typeof field.label === 'string' ? field.label : String(field.label),
        type: attributeType,
        required: field.required || false,
        placeholder: field.placeholder,
        default: field.defaultValue,
        editable: true,
        visible: true,
        minRows: field.minRows,
        maxRows: field.maxRows,
        validation: field.validator,
        options: options
      };
    });
  }, [fields, multiStep, step1Fields]);

  // Initialize form data with default values
  const initialFormData = useMemo(() => {
    const data: any = {};
    const fieldsToUse = multiStep ? step1Fields : fields;
    fieldsToUse.forEach(field => {
      if (field.type === 'multiselect') {
        // Multiselect fields should default to empty array
        data[field.key] = field.defaultValue || [];
      } else if (field.type === 'boolean') {
        // Boolean fields should default to false
        data[field.key] = field.defaultValue !== undefined ? field.defaultValue : false;
      } else {
        // Other fields default to empty string or provided default
        data[field.key] = field.defaultValue !== undefined ? field.defaultValue : '';
      }
    });
    return data;
  }, [fields, multiStep, step1Fields]);

  const handleButtonClick = () => {
    if (!disabled && !loading && !isCreating) {
      setIsPopupOpen(true);
      // Reset to step 1 when opening popup
      if (multiStep) {
        setCurrentStep(1);
        setStep1Data({});
        setAddressData({ street: '', postalCode: '', city: '' });
      }
    }
  };

  const handleStep1Next = (formData: any) => {
    // Validate label is present
    if (!formData.label || !formData.label.trim()) {
      return; // FormGeneratorForm will show validation error
    }
    setStep1Data(formData);
    setCurrentStep(2);
  };

  const handleStep2Back = () => {
    setCurrentStep(1);
  };

  const handleStep2Finish = async (step2FormData: any) => {
    // Combine step 1 and step 2 data
    const selectedParcels = step2FormData.parzellen || [];
    const completeData: any = {
      label: step1Data.label,
      // mandateId is NOT included - will be set by backend
    };

    // Add parzellen array if parcels were selected - include ALL parcel information for each
    if (selectedParcels && selectedParcels.length > 0) {
      completeData.parzellen = selectedParcels.map((selectedParcel: any) => ({
        // Basic parcel info
        id: selectedParcel.parcel.id,
        egrid: selectedParcel.parcel.egrid,
        number: selectedParcel.parcel.number,
        name: selectedParcel.parcel.name,
        identnd: selectedParcel.parcel.identnd,
        canton: selectedParcel.parcel.canton,
        municipality_code: selectedParcel.parcel.municipality_code,
        municipality_name: selectedParcel.parcel.municipality_name,
        address: selectedParcel.parcel.address,
        area_m2: selectedParcel.parcel.area_m2,
        centroid: selectedParcel.parcel.centroid,
        geoportal_url: selectedParcel.parcel.geoportal_url,
        realestate_type: selectedParcel.parcel.realestate_type,
        
        // User-entered address fields (from step 2)
        userAddress: {
          street: step2FormData.address.street,
          postalCode: step2FormData.address.postalCode,
          city: step2FormData.address.city
        },
        
        // Geometry and map data
        geometry: selectedParcel.map_view?.geometry_geojson,
        perimeter: selectedParcel.parcel.perimeter,
        map_view: selectedParcel.map_view,
        
        // Adjacent parcels
        adjacent_parcels: selectedParcel.adjacent_parcels || [],
        
        // Include any other parcel properties that might exist
        ...selectedParcel.parcel
      }));
    }

    // Send request to backend via onCreate handler
    setIsCreating(true);
    try {
      const result = await onCreate(completeData);
      
      if (result?.success !== false) {
        // Success - close popup
        setIsPopupOpen(false);
        setCurrentStep(1);
        setStep1Data({});
        setAddressData({ street: '', postalCode: '', city: '' });
        
        if (onSuccess) {
          onSuccess(result);
        }
      } else {
        // Handle error
        if (onError) {
          onError(result?.error || 'Projekt konnte nicht erstellt werden');
        }
      }
    } catch (error: any) {
      console.error('Project creation failed:', error);
      if (onError) {
        onError(error.message || 'Projekt konnte nicht erstellt werden');
      }
    } finally {
      setIsCreating(false);
    }
  };

  const handleSave = async (updatedData: any) => {
    if (multiStep && currentStep === 1) {
      handleStep1Next(updatedData);
      return;
    }

    setIsCreating(true);
    
    try {
      const result = await onCreate(updatedData);
      
      if (result?.success !== false) {
        // Success
        setIsPopupOpen(false);
        if (multiStep) {
          setCurrentStep(1);
          setStep1Data({});
          setAddressData({ street: '', postalCode: '', city: '' });
        }
        if (onSuccess) {
          onSuccess(result);
        }
      } else {
        // Handle error
        if (onError) {
          onError(result?.error || 'Creation failed');
        }
      }
    } catch (error: any) {
      console.error('Creation failed:', error);
      if (onError) {
        onError(error.message || 'Creation failed');
      }
    } finally {
      setIsCreating(false);
    }
  };

  const handleCancel = () => {
    setIsPopupOpen(false);
    if (multiStep) {
      setCurrentStep(1);
      setStep1Data({});
      setAddressData({ street: '', postalCode: '', city: '' });
    }
  };

  const handleAddressChange = (field: string, value: string) => {
    setAddressData(prev => ({
      ...prev,
      [field]: value
    }));
  };

  const isDisabled = disabled || loading || isCreating;
  
  // Resolve language text for popup title
  const resolvedPopupTitle = typeof popupTitle === 'string' 
    ? t(popupTitle, popupTitle) 
    : popupTitle;

  // Resolve language text for attributes
  const resolvedAttributes: AttributeDefinition[] = useMemo(() => {
    return attributes.map(attr => ({
      ...attr,
      label: typeof attr.label === 'string' ? t(attr.label, attr.label) : attr.label,
      placeholder: attr.placeholder 
        ? (typeof attr.placeholder === 'string' ? t(attr.placeholder, attr.placeholder) : attr.placeholder)
        : undefined
    }));
  }, [attributes, t]);

  return (
    <>
      <Button
        {...props}
        variant={variant}
        size={size}
        disabled={isDisabled}
        loading={false}
        className={`createButton ${className}`}
        onClick={handleButtonClick}
        icon={isCreating ? undefined : icon}
        iconPosition={iconPosition}
      >
        {isCreating && (
          <div className="spinnerIcon" style={{ marginRight: '8px' }} />
        )}
        {children || (isCreating ? t('common.creating', 'Creating...') : t('common.create', 'Create'))}
      </Button>

      {/* Create Popup */}
      <Popup
        isOpen={isPopupOpen}
        title={resolvedPopupTitle}
        onClose={handleCancel}
        size={multiStep ? 'large' : popupSize}
        closable={!isCreating}
      >
        {multiStep ? (
          currentStep === 1 ? (
            <div className={styles.step1Container}>
              <div className={styles.stepIndicator}>
                <span className={styles.stepNumber}>1</span>
                <span className={styles.stepLabel}>Titel festlegen</span>
              </div>
              <FormGeneratorForm
                attributes={resolvedAttributes}
                data={initialFormData}
                mode="create"
                onSubmit={handleSave}
                onCancel={handleCancel}
                submitButtonText={t('common.next', 'Weiter')}
                cancelButtonText={t('common.cancel', 'Abbrechen')}
              />
            </div>
          ) : (
            <PekProvider>
              <Step2Content
                onNext={handleStep2Finish}
                onBack={handleStep2Back}
                addressData={addressData}
                onAddressChange={handleAddressChange}
              />
            </PekProvider>
          )
        ) : (
          <FormGeneratorForm
            attributes={resolvedAttributes}
            data={initialFormData}
            mode="create"
            onSubmit={handleSave}
            onCancel={handleCancel}
            submitButtonText={t('common.create', 'Create')}
            cancelButtonText={t('common.cancel', 'Cancel')}
          />
        )}
      </Popup>
    </>
  );
};

export default CreateButton;

