<template>
  <div class="geocode-search">
    <div class="search-input-wrapper">
      <input
        ref="searchInput"
        v-model="searchQuery"
        type="text"
        class="search-input"
        placeholder="Rechercher une adresse..."
        @input="handleInput"
        @keydown.escape="clearSearch"
        @keydown.enter.prevent="selectFirstResult"
        @keydown.down.prevent="navigateResults(1)"
        @keydown.up.prevent="navigateResults(-1)"
      />
      <button
        v-if="searchQuery"
        type="button"
        class="clear-button"
        @click="clearSearch"
        title="Effacer"
      >
        <k-icon type="cancel" />
      </button>
      <div v-if="isLoading" class="search-spinner">
        <div class="spinner-icon"></div>
      </div>
    </div>

    <!-- Results dropdown -->
    <div v-if="showResults" class="results-dropdown">
      <div v-if="error" class="error-message">
        <k-icon type="alert" />
        <span>{{ error }}</span>
      </div>

      <div v-else-if="results.length === 0 && !isLoading" class="no-results">
        Aucun résultat trouvé
      </div>

      <div v-else class="results-list">
        <div
          v-for="(result, index) in results"
          :key="result.id"
          class="result-item"
          :class="{ active: index === selectedIndex }"
          @click="selectResult(result)"
          @mouseenter="selectedIndex = index"
        >
          <div class="result-icon">
            <k-icon type="pin" />
          </div>
          <div class="result-content">
            <div class="result-name">{{ result.displayName }}</div>
            <div class="result-coords">
              {{ result.lat.toFixed(6) }}, {{ result.lon.toFixed(6) }}
            </div>
          </div>
        </div>
      </div>

      <div v-if="results.length > 0" class="results-footer">
        <small>Powered by OpenStreetMap Nominatim</small>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, watch } from 'vue';
import { geocode } from '../../utils/api/nominatim.js';
import { debounce } from '../../utils/helpers/debounce.js';
import { DEBOUNCE_DELAYS } from '../../utils/constants.js';

export default {
  emits: ['select-location', 'center-map'],

  setup(props, { emit }) {
    const searchInput = ref(null);
    const searchQuery = ref('');
    const results = ref([]);
    const isLoading = ref(false);
    const error = ref(null);
    const showResults = ref(false);
    const selectedIndex = ref(-1);

    // Debounced search function
    const debouncedSearch = debounce(async (query) => {
      if (!query || query.trim().length < 3) {
        results.value = [];
        showResults.value = false;
        isLoading.value = false;
        return;
      }

      isLoading.value = true;
      error.value = null;

      try {
        const data = await geocode(query);
        results.value = data;
        showResults.value = true;
        selectedIndex.value = -1;
      } catch (err) {
        error.value = 'Erreur lors de la recherche. Veuillez réessayer.';
        results.value = [];
      } finally {
        isLoading.value = false;
      }
    }, DEBOUNCE_DELAYS.GEOCODING);

    function handleInput() {
      debouncedSearch(searchQuery.value);
    }

    function selectResult(result) {
      emit('select-location', {
        lat: result.lat,
        lon: result.lon,
        displayName: result.displayName,
      });
      searchQuery.value = result.displayName;
      showResults.value = false;
    }

    function selectFirstResult() {
      if (results.value.length > 0) {
        selectResult(results.value[0]);
      }
    }

    function navigateResults(direction) {
      if (!showResults.value || results.value.length === 0) {
        return;
      }

      selectedIndex.value += direction;

      if (selectedIndex.value < 0) {
        selectedIndex.value = results.value.length - 1;
      } else if (selectedIndex.value >= results.value.length) {
        selectedIndex.value = 0;
      }
    }

    function clearSearch() {
      searchQuery.value = '';
      results.value = [];
      showResults.value = false;
      error.value = null;
      selectedIndex.value = -1;
    }

    function focus() {
      if (searchInput.value) {
        searchInput.value.focus();
      }
    }

    // Close dropdown when clicking outside
    function handleClickOutside(event) {
      if (!event.target.closest('.geocode-search')) {
        showResults.value = false;
      }
    }

    // Add/remove click outside listener
    watch(showResults, (newValue) => {
      if (newValue) {
        setTimeout(() => {
          document.addEventListener('click', handleClickOutside);
        }, 100);
      } else {
        document.removeEventListener('click', handleClickOutside);
      }
    });

    return {
      searchInput,
      searchQuery,
      results,
      isLoading,
      error,
      showResults,
      selectedIndex,
      handleInput,
      selectResult,
      selectFirstResult,
      navigateResults,
      clearSearch,
      focus,
    };
  },
};
</script>

<style>
.geocode-search {
  position: relative;
  width: 100%;
}

.search-input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.search-input {
  width: 100%;
  padding: 0.625rem 2.5rem 0.625rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--rounded-sm);
  font-size: 0.875rem;
  background: var(--color-white);
  transition: border-color 0.2s;
  color: #000;
}

.search-input:focus {
  outline: none;
  border-color: var(--color-focus);
  box-shadow: 0 0 0 2px var(--color-focus-outline);
}

.clear-button {
  position: absolute;
  right: 0.5rem;
  background: none;
  border: none;
  padding: 0.25rem;
  cursor: pointer;
  color: var(--color-text-light);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s;
}

.clear-button:hover {
  color: var(--color-text);
}

.search-spinner {
  position: absolute;
  right: 0.75rem;
  pointer-events: none;
}

.spinner-icon {
  width: 16px;
  height: 16px;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-focus);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.results-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 0.25rem;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--rounded-sm);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  max-height: 300px;
  overflow-y: auto;
  z-index: 1000;
}

.error-message {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem;
  color: var(--color-negative);
  font-size: 0.875rem;
}

.no-results {
  padding: 1rem;
  text-align: center;
  color: var(--color-text-light);
  font-size: 0.875rem;
}

.results-list {
  display: flex;
  flex-direction: column;
}

.result-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem;
  cursor: pointer;
  transition: background-color 0.2s;
  border-bottom: 1px solid var(--color-background);
}

.result-item:last-child {
  border-bottom: none;
}

.result-item:hover,
.result-item.active {
  background: var(--color-focus-outline);
}

.result-icon {
  flex-shrink: 0;
  color: var(--color-text-light);
  padding-top: 0.125rem;
}

.result-content {
  flex: 1;
  min-width: 0;
}

.result-name {
  font-size: 0.875rem;
  margin-bottom: 0.25rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #000;
}

.result-coords {
  font-size: 0.75rem;
  color: var(--color-text-light);
  font-family: monospace;
}

.results-footer {
  padding: 0.5rem;
  border-top: 1px solid var(--color-border);
  text-align: center;
}

.results-footer small {
  font-size: 0.7rem;
  color: var(--color-text-light);
}
</style>
