import React, { useState, useCallback, useRef, useEffect } from 'react';
import {
  GoogleMap,
  useJsApiLoader,
  Marker,
  Autocomplete,
} from '@react-google-maps/api';
import { useMaps } from '../stores/useMaps';
import { LocateFixed, MapPinIcon } from 'lucide-react';
import { Button } from '@chakra-ui/react';

const containerStyle = {
  width: '100%',
  height: '400px',
};

const defaultCenter = {
  lat: -6.2,
  lng: 106.816666,
};

const PinpointLocation = ({ initialLatitude, initialLongitude, initialAddress }) => {
  const { isLoaded } = useJsApiLoader({
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY,
    libraries: ['places'],
  });

  const {
    addressMaps,
    setAddressMaps,
    selectedPosition,
    setSelectedPosition,
    setDetailAddress,
    setPinedMaps,
  } = useMaps();

  const [tempAddress, setTempAddress] = useState(initialAddress || '');
  const [tempPosition, setTempPosition] = useState(
    initialLatitude && initialLongitude 
      ? { lat: parseFloat(initialLatitude), lng: parseFloat(initialLongitude) }
      : selectedPosition.lat && selectedPosition.lng
        ? selectedPosition
        : defaultCenter
  );

  const [markerIcon, setMarkerIcon] = useState(null);

  const autocompleteRef = useRef(null);

  useEffect(() => {
    if (isLoaded && window.google) {
      setMarkerIcon({
        url: 'https://cdn.pixabay.com/photo/2014/04/03/10/03/google-309740_1280.png',
        scaledSize: new window.google.maps.Size(25, 40),
      });
    }

    // If we have initial coordinates but no address, fetch the address
    if (initialLatitude && initialLongitude && !initialAddress) {
      getAddress(parseFloat(initialLatitude), parseFloat(initialLongitude));
    }
  }, [isLoaded, initialLatitude, initialLongitude, initialAddress]);

  const getAddressComponent = (components, type) => {
    const component = components.find((comp) => comp.types.includes(type));
    return component ? component.long_name : '';
  };

  const getAddress = async (lat, lng) => {
    try {
      const response = await fetch(
        `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.NEXT_PUBLIC_GOOGLE_API_KEY}`
      );
      const data = await response.json();

      if (data.results[0]) {
        const addressComponents = data.results[0].address_components;
        const formattedAddress = data.results[0].formatted_address;

        const details = {
          street:
            getAddressComponent(addressComponents, 'route') +
            ' ' +
            getAddressComponent(addressComponents, 'street_number'),
          province: getAddressComponent(addressComponents, 'administrative_area_level_1'),
          district: getAddressComponent(addressComponents, 'administrative_area_level_2'),
          subDistrict: getAddressComponent(addressComponents, 'administrative_area_level_3'),
          village: getAddressComponent(addressComponents, 'administrative_area_level_4'),
          postalCode: getAddressComponent(addressComponents, 'postal_code'),
        };

        setDetailAddress(details);
        setTempAddress(formattedAddress);
      }
    } catch (error) {
      console.error('Error fetching address:', error);
    }
  };

  const onMapClick = useCallback((event) => {
    const lat = event.latLng.lat();
    const lng = event.latLng.lng();
    const newPosition = { lat, lng };
    setTempPosition(newPosition);
    getAddress(lat, lng);
  }, []);

  const handlePlaceSelect = () => {
    const place = autocompleteRef.current.getPlace();
    if (place && place.geometry) {
      const lat = place.geometry.location.lat();
      const lng = place.geometry.location.lng();
      const newPosition = { lat, lng };
      setTempPosition(newPosition);
      setTempAddress(place.formatted_address);
      getAddress(lat, lng);
    }
  };

  const handleUseCurrentLocation = () => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const lat = position.coords.latitude;
          const lng = position.coords.longitude;
          const newPosition = { lat, lng };
          setTempPosition(newPosition);
          getAddress(lat, lng);
        },
        (error) => {
          console.error('Error getting current location:', error);
        }
      );
    }
  };

  const handleSavePinpoint = (event) => {
    event.preventDefault();
    if (tempAddress === '') {
      alert('Silahkan pilih lokasi terlebih dahulu');
      return;
    }

    setSelectedPosition(tempPosition);
    setAddressMaps(tempAddress);
    setPinedMaps(false);
  };

  return (
    <div className='w-full'>
      <h3>Tentukan Pinpoint Lokasi</h3>

      <div style={{ marginBottom: '10px' }}>
        {isLoaded ? (
          <Autocomplete
            onLoad={(ref) => (autocompleteRef.current = ref)}
            onPlaceChanged={handlePlaceSelect}
          >
            <input
              type='text'
              placeholder='Cari Alamat...'
              value={tempAddress}
              onChange={(e) => setTempAddress(e.target.value)}
              style={{ width: '100%', padding: '8px' }}
            />
          </Autocomplete>
        ) : (
          <p>Loading autocomplete...</p>
        )}
      </div>

      <div>
        {isLoaded ? (
          <GoogleMap
            mapContainerStyle={containerStyle}
            center={tempPosition}
            zoom={15}
            onClick={onMapClick}
          >
            {markerIcon && (
              <Marker
                position={tempPosition}
                draggable={true}
                onDragEnd={(e) => {
                  const lat = e.latLng.lat();
                  const lng = e.latLng.lng();
                  const newPosition = { lat, lng };
                  setTempPosition(newPosition);
                  getAddress(lat, lng);
                }}
                icon={markerIcon}
              />
            )}
          </GoogleMap>
        ) : (
          <p>Loading map...</p>
        )}
      </div>

      <div style={{ marginTop: '20px' }}>
        <Button variant='solid' onClick={handleUseCurrentLocation}>
          <LocateFixed className='h-6 w-6 text-gray-500 mr-2' /> Gunakan Lokasi Saat Ini
        </Button>
      </div>

      <div style={{ marginTop: '10px' }}>
        <p>PinPoint :</p>
        <div className='flex gap-x-2 shadow-md rounded-sm text-gray-500 p-3 items-center'>
          <MapPinIcon className='h-8 w-8 text-gray-500 mr-3' />
          <label>{tempAddress || 'Pilih lokasi di peta'}</label>
        </div>
      </div>

      <div className='mt-6 flex justify-end'>
        <button
          className='p-3 border border-red-500 bg-red-600 text-white font-semibold rounded-lg'
          onClick={handleSavePinpoint}
        >
          Simpan Lokasi Ini
        </button>
      </div>
    </div>
  );
};

export default PinpointLocation;