<template>
  <div class="wrapper">
    <label>{{ label }}</label>
    <p v-if="value && !place">{{ value }}</p>
    <p v-if="place">{{ place.address }}</p>
    <p v-show="error" class="error">{{ error }}</p>

    <div class="input-and-btn">
      <button class="geo-btn" type="button" @click="getGeoLocation">
        <v-progress-circular
          v-if="loading"
          :size="15"
          :width="2"
          indeterminate
        />
        <v-icon v-else small class="geo-icon"> mdi-crosshairs-gps </v-icon>
      </button>
      <input
        ref="googleMap"
        :required="!value"
        placeholder=""
        type="search"
        @focus="clear"
      />

      <!-- <button class="add-btn" type="button" @click="logPlace">Añadir</button> -->
    </div>
  </div>
</template>

<script>
import { Loader } from '@googlemaps/js-api-loader'
export default {
  props: {
    value: {
      type: String,
      default: '',
    },
    geo: {
      type: Object,
      default: null,
    },
    label: {
      type: String,
      default: 'Dirección',
    },
  },
  emits: ['addedData'],
  data() {
    return {
      google: null,
      autocomplete: null,
      geocoder: null,
      place: null,
      error: null,
      loading: false,
    }
  },

  async mounted() {
    const config = useRuntimeConfig()
    const apiKey = config.public.googleMapsApiKey
    if (!apiKey) {
      console.error('Google Maps API key is not defined in the runtime config.')
      return
    }
    const googleMapApi = new Loader({
      libraries: ['places'],
      apiKey: apiKey,
    })

    try {
      await googleMapApi.load()
      await this.initializeMap()
    } catch (error) {
      console.error('Error loading Google Maps API:', error)
      this.error = 'Error al cargar el mapa de Google'
    }
  },
  methods: {
    initializeMap() {
      const mapContainer = this.$refs.googleMap

      if (!mapContainer || !window.google) {
        this.error = 'Google Maps no disponible'
        return
      }

      this.autocomplete = new window.google.maps.places.PlaceAutocompleteElement(mapContainer)
      window.google.maps.event.addListener(this.autocomplete, 'place_changed', () => this.logPlace())
      this.geocoder = new window.google.maps.Geocoder()
      if (this.geo) {
        this.getGeoData(this.geo)
      }
    },

    async getGeoLocation() {
      this.place = null
      this.error = null
      const geoLocation = () =>
        new Promise((resolve, reject) => {
          if (!navigator.geolocation) {
            reject(new Error('Geolocalización no soportada'))
            return
          }
          navigator.geolocation.getCurrentPosition(
            (posData) => {
              resolve(posData)
            },
            (error) => {
              reject(error)
            }
          )
        } )
      try {
        this.loading = true
        const position = await geoLocation()
        const geo = {
          lat: position.coords.latitude,
          lng: position.coords.longitude,
        }
        this.getGeoData(geo)
      } catch (error) {
        console.error(error)
        this.error = 'No se puede obtener la ubicación'
        this.loading = false
      }
    },

    getGeoData(coordinates) {
      if (!this.geocoder) {
        this.error = 'Geocoder no inicializado'
        this.loading = false
        return
      }

      this.geocoder.geocode({ location: coordinates }, (result, status) => {
        if (status === 'OK') {
          const data = result[0]
          const address = data.formatted_address
          const geo = {
            latitude: Number(data.geometry.location.lat().toFixed(4)),
            longitude: Number(data.geometry.location.lng().toFixed(4)),
          }
          const city = data.address_components.find(
              (element) => element.types[0] === 'locality'
            ).long_name || ''
          this.place = { address, geo, city }
          if (this.$refs.googleMap) {
            this.$refs.googleMap.value = this.place.address
          }
          this.$emit('addedData', this.place)
          this.loading = false
        } else {
          this.error = 'No se puede obtener la ubicación'
          this.loading = false
        }
      })
    },

    clear() {
      this.place = null
      this.error = null
      this.$refs.googleMap.value = null
      this.$emit('addedData', this.place)
    },

    async logPlace() {
      this.place = null
      this.error = null
      try {
        const googlePlace = await this.autocomplete.getPlace()
        console.log('Google Place:', googlePlace)
        const address = googlePlace.formatted_address
        const geo = {
          latitude: Number(googlePlace.geometry.location.lat().toFixed(4)),
          longitude: Number(googlePlace.geometry.location.lng().toFixed(4)),
        }
        const city =
          googlePlace.address_components.find(
            (element) => element.types[0] === 'locality'
          )?.long_name || ''
        this.place = { address, geo, city }
        this.$emit('addedData', this.place)
      } catch {
        this.place = null
        this.error = 'Debe introducir una dirección correcta'
      }
    },
  },
}
</script>

<style lang="scss" scoped>
label {
  text-align: left;
  color: $color-navy;
  font-weight: $bold;
  font-size: $xs;
  display: block;
}

input {
  width: 100%;
  background-color: $color-grey-inputs;
  border: 1px solid $color-grey-inputs-border;
  border-radius: 4px;
  padding: 9px 5px;
  display: block;
  outline: none;
  font-size: $s;
}

.input-and-btn {
  width: 100%;
  display: flex;
  justify-content: space-between;

  input {
    width: 90%;
  }

  button {
    height: auto;
    background-color: $color-navy;
    color: $color-light;
    border: 1px solid $color-navy;
    border-radius: 5px;
    text-transform: uppercase;
    padding: 5px 5px;
    font-size: $xxs;

    @include mobile {
      font-size: $xxs;
    }
  }
  .geo-btn {
    width: 10%;
    min-width: 30px;
  }
  // .add-btn {
  //   width: 20%;
  // }
}

.error {
  color: $color-error;
}

.geo-icon {
  color: $color-light !important;
}
</style>
