import React, { useEffect, useState, useMemo } from 'react';
import { Autocomplete, Box, Grid, TextField, Typography } from '@mui/material';
import LocationOnIcon from '@mui/icons-material/LocationOn';
import parse from 'autosuggest-highlight/parse';
import debounce from 'lodash.debounce';

const GOOGLE_MAPS_API_KEY = process.env.REACT_APP_GOOGLE_MAPS_API_KEY;

let autocompleteService = null;

const loadGoogleMapsScript = () => {
  if (!document.querySelector('#google-maps')) {
    const script = document.createElement('script');
    script.id = 'google-maps';
    script.src = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API_KEY}&libraries=places`;
    script.async = true;
    script.defer = true;
    document.head.appendChild(script);
  }
};

const AddressAutocomplete = ({ onSelect }) => {
  const [inputValue, setInputValue] = useState('');
  const [options, setOptions] = useState([]);
  const [value, setValue] = useState(null);

  const fetchSuggestions = useMemo(
    () =>
      debounce((input, callback) => {
        if (autocompleteService && input) {
          autocompleteService.getPlacePredictions({ input }, callback);
        }
      }, 400),
    []
  );

  useEffect(() => {
    loadGoogleMapsScript();

    const interval = setInterval(() => {
      if (window.google?.maps?.places && !autocompleteService) {
        autocompleteService = new window.google.maps.places.AutocompleteService();
        clearInterval(interval);
      }
    }, 300);

    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    if (!inputValue || !autocompleteService) return;

    let active = true;

    fetchSuggestions(inputValue, (results) => {
      if (active) {
        setOptions(results || []); // fallback to [] if results is null
      }
    });

    return () => {
      active = false;
    };
  }, [inputValue, fetchSuggestions]);

  const handleSelect = async (event, newValue) => {
    if (!newValue || !newValue.place_id) {
      setValue(null);
      setInputValue('');
      setOptions([]);
      if (onSelect) onSelect(null); // clear form
      return;
    }

    setValue(newValue);
    setInputValue(newValue?.description || '');

    try {
      const placeService = new window.google.maps.places.PlacesService(document.createElement('div'));

      placeService.getDetails({ placeId: newValue.place_id }, (place, status) => {
        if (status !== window.google.maps.places.PlacesServiceStatus.OK || !place || !place.geometry || !place.address_components) {
          console.warn('Invalid place data');
          if (onSelect) onSelect(null);
          return;
        }

        const extract = (type) => place.address_components.find((c) => c.types.includes(type))?.long_name || '';

        const result = {
          address: `${place.name}, ${place.formatted_address}`,
          suburb: extract('sublocality_level_1'),
          city: extract('locality'),
          state: extract('administrative_area_level_1'),
          postcode: extract('postal_code'),
          latitude: place.geometry.location.lat().toString(),
          longitude: place.geometry.location.lng().toString()
        };

        if (onSelect) onSelect(result);
      });
    } catch (err) {
      console.error('Place fetch error:', err);
      if (onSelect) onSelect(null);
    }
  };

  return (
    <Autocomplete
      fullWidth
      options={options}
      getOptionLabel={(option) => (typeof option === 'string' ? option : option?.description || '')}
      filterOptions={(x) => x}
      autoComplete
      includeInputInList
      filterSelectedOptions
      value={value}
      noOptionsText="No matching addresses"
      onChange={handleSelect}
      onInputChange={(e, newVal) => setInputValue(newVal)}
      renderInput={(params) => <TextField {...params} placeholder="Search address..." fullWidth />}
      renderOption={(props, option) => {
        if (!option?.structured_formatting) return null;

        const matches = option.structured_formatting.main_text_matched_substrings || [];
        const parts = parse(
          option.structured_formatting.main_text || '',
          matches.map((m) => [m.offset, m.offset + m.length])
        );

        return (
          <li {...props}>
            <Grid container alignItems="center">
              <Grid item sx={{ width: 44, display: 'flex' }}>
                <LocationOnIcon sx={{ color: 'text.secondary' }} />
              </Grid>
              <Grid item sx={{ width: 'calc(100% - 44px)', wordWrap: 'break-word' }}>
                {parts.map((part, index) => (
                  <Box key={index} component="span" sx={{ fontWeight: part.highlight ? 'bold' : 'regular' }}>
                    {part.text}
                  </Box>
                ))}
                <Typography variant="body2" color="text.secondary">
                  {option.structured_formatting.secondary_text}
                </Typography>
              </Grid>
            </Grid>
          </li>
        );
      }}
    />
  );
};

export default AddressAutocomplete;
