import { t, i18n } from '../i18n.js'
import { escapeHTML } from '../utils/helpers.js'

const NOMINATIM_URL = 'https://nominatim.openstreetmap.org/search'
const DEBOUNCE_MS = 400
const MIN_QUERY_LENGTH = 2

class LocationPicker extends HTMLElement {
    constructor() {
        super()
        this.suggestions = []
        this.selectedLocation = null
        this.loading = false
        this.debounceTimer = null
        this.isOpen = false
    }

    static get observedAttributes() {
        return ['value', 'placeholder', 'country']
    }

    connectedCallback() {
        this.render()
        this.setupEventListeners()
        this.unsubscribe = i18n.subscribe(() => this.render())
    }

    disconnectedCallback() {
        if (this.unsubscribe) this.unsubscribe()
        if (this.debounceTimer) clearTimeout(this.debounceTimer)
        document.removeEventListener('click', this.handleOutsideClick)
    }

    get value() {
        return this.selectedLocation
    }

    set value(location) {
        this.selectedLocation = location
        const input = this.querySelector('.location-input')
        if (input && location) {
            input.value = this.formatLocationDisplay(location)
        }
    }

    render() {
        const placeholder = this.getAttribute('placeholder') || t('create.locationPlaceholder') || 'Stadt, PLZ oder Adresse'
        const currentValue = this.selectedLocation ? this.formatLocationDisplay(this.selectedLocation) : ''

        this.innerHTML = /* html */`
            <div class="location-picker">
                <div class="input-wrapper">
                    <input 
                        type="text" 
                        class="input location-input" 
                        placeholder="${placeholder}"
                        value="${currentValue}"
                        autocomplete="off"
                    >
                    ${this.loading ? '<span class="loading-indicator"></span>' : ''}
                </div>
                <div class="suggestions-dropdown ${this.isOpen && this.suggestions.length > 0 ? 'open' : ''}">
                    ${this.renderSuggestions()}
                </div>
            </div>
        `
        this.setupEventListeners()
    }

    renderSuggestions() {
        if (this.suggestions.length === 0) return ''

        return this.suggestions.map((loc, index) => /* html */`
            <div class="suggestion-item" data-index="${index}">
                <span class="suggestion-icon">📍</span>
                <div class="suggestion-text">
                    <span class="suggestion-name">${escapeHTML(loc.displayName)}</span>
                    <span class="suggestion-detail">${escapeHTML(loc.detail)}</span>
                </div>
            </div>
        `).join('')
    }

    setupEventListeners() {
        const input = this.querySelector('.location-input')
        const dropdown = this.querySelector('.suggestions-dropdown')

        input?.addEventListener('input', (e) => this.handleInput(e.target.value))
        input?.addEventListener('focus', () => this.handleFocus())
        input?.addEventListener('keydown', (e) => this.handleKeydown(e))

        dropdown?.querySelectorAll('.suggestion-item').forEach(item => {
            item.addEventListener('click', () => {
                const index = parseInt(item.dataset.index)
                this.selectSuggestion(index)
            })
        })

        this.handleOutsideClick = (e) => {
            if (!this.contains(e.target)) {
                this.closeSuggestions()
            }
        }
        document.addEventListener('click', this.handleOutsideClick)
    }

    handleInput(query) {
        if (this.debounceTimer) clearTimeout(this.debounceTimer)

        if (query.length < MIN_QUERY_LENGTH) {
            this.suggestions = []
            this.isOpen = false
            this.updateDropdown()
            return
        }

        this.debounceTimer = setTimeout(() => {
            this.searchLocations(query)
        }, DEBOUNCE_MS)
    }

    handleFocus() {
        if (this.suggestions.length > 0) {
            this.isOpen = true
            this.updateDropdown()
        }
    }

    handleKeydown(e) {
        if (e.key === 'Escape') {
            this.closeSuggestions()
        } else if (e.key === 'ArrowDown' && this.isOpen) {
            e.preventDefault()
            this.focusNextSuggestion(1)
        } else if (e.key === 'ArrowUp' && this.isOpen) {
            e.preventDefault()
            this.focusNextSuggestion(-1)
        } else if (e.key === 'Enter' && this.isOpen) {
            e.preventDefault()
            const focused = this.querySelector('.suggestion-item.focused')
            if (focused) {
                const index = parseInt(focused.dataset.index)
                this.selectSuggestion(index)
            }
        }
    }

    focusNextSuggestion(direction) {
        const items = this.querySelectorAll('.suggestion-item')
        if (items.length === 0) return

        const currentFocused = this.querySelector('.suggestion-item.focused')
        let nextIndex = 0

        if (currentFocused) {
            const currentIndex = parseInt(currentFocused.dataset.index)
            nextIndex = currentIndex + direction
            if (nextIndex < 0) nextIndex = items.length - 1
            if (nextIndex >= items.length) nextIndex = 0
            currentFocused.classList.remove('focused')
        }

        items[nextIndex]?.classList.add('focused')
    }

    async searchLocations(query) {
        this.loading = true
        this.updateLoadingState()

        try {
            const countryCode = this.getAttribute('country') || ''
            const params = new URLSearchParams({
                q: query,
                format: 'json',
                addressdetails: '1',
                limit: '6',
                'accept-language': document.documentElement.lang || 'de'
            })

            if (countryCode) {
                params.set('countrycodes', countryCode)
            }

            const response = await fetch(`${NOMINATIM_URL}?${params}`, {
                headers: {
                    'User-Agent': 'dgray.io/1.0'
                }
            })

            if (!response.ok) throw new Error('Nominatim request failed')

            const results = await response.json()
            this.suggestions = results.map(r => this.parseNominatimResult(r))
            this.isOpen = this.suggestions.length > 0
        } catch (error) {
            console.error('Location search failed:', error)
            this.suggestions = []
            this.isOpen = false
        } finally {
            this.loading = false
            this.updateDropdown()
            this.updateLoadingState()
        }
    }

    parseNominatimResult(result) {
        const addr = result.address || {}
        
        const city = addr.city || addr.town || addr.village || addr.municipality || addr.county || ''
        const postalCode = addr.postcode || ''
        const country = addr.country || ''
        const countryCode = addr.country_code?.toUpperCase() || ''

        let displayName = city
        if (postalCode && city) {
            displayName = `${postalCode} ${city}`
        } else if (postalCode) {
            displayName = postalCode
        }

        const detail = country

        const region = addr.state || addr.county || ''

        return {
            displayName,
            detail,
            name: city,
            postalCode,
            region,
            country,
            countryCode,
            lat: parseFloat(result.lat),
            lng: parseFloat(result.lon),
            raw: result
        }
    }

    selectSuggestion(index) {
        const location = this.suggestions[index]
        if (!location) return

        this.selectedLocation = location
        const input = this.querySelector('.location-input')
        if (input) {
            input.value = this.formatLocationDisplay(location)
        }

        this.closeSuggestions()

        this.dispatchEvent(new CustomEvent('location-select', {
            bubbles: true,
            detail: location
        }))
    }

    formatLocationDisplay(location) {
        if (!location) return ''
        const parts = []
        if (location.postalCode) parts.push(location.postalCode)
        if (location.name) parts.push(location.name)
        if (location.countryCode) parts.push(location.countryCode)
        return parts.join(', ')
    }

    closeSuggestions() {
        this.isOpen = false
        this.updateDropdown()
    }

    updateDropdown() {
        const dropdown = this.querySelector('.suggestions-dropdown')
        if (dropdown) {
            dropdown.className = `suggestions-dropdown ${this.isOpen && this.suggestions.length > 0 ? 'open' : ''}`
            dropdown.innerHTML = this.renderSuggestions()
            
            dropdown.querySelectorAll('.suggestion-item').forEach(item => {
                item.addEventListener('click', () => {
                    const index = parseInt(item.dataset.index)
                    this.selectSuggestion(index)
                })
            })
        }
    }

    updateLoadingState() {
        const wrapper = this.querySelector('.input-wrapper')
        if (!wrapper) return

        let indicator = wrapper.querySelector('.loading-indicator')
        if (this.loading && !indicator) {
            indicator = document.createElement('span')
            indicator.className = 'loading-indicator'
            wrapper.appendChild(indicator)
        } else if (!this.loading && indicator) {
            indicator.remove()
        }
    }

    getLocationData() {
        if (!this.selectedLocation) return null
        return {
            name: this.selectedLocation.name,
            postal_code: this.selectedLocation.postalCode,
            country: this.selectedLocation.countryCode,
            lat: this.selectedLocation.lat,
            lng: this.selectedLocation.lng
        }
    }
}

customElements.define('location-picker', LocationPicker)

const style = document.createElement('style')
style.textContent = /* css */`
    location-picker {
        display: block;
        position: relative;
    }

    location-picker .location-picker {
        position: relative;
    }

    location-picker .input-wrapper {
        position: relative;
    }

    location-picker .location-input {
        width: 100%;
        padding-right: 36px;
    }

    location-picker .loading-indicator {
        position: absolute;
        right: 12px;
        top: 50%;
        transform: translateY(-50%);
        width: 16px;
        height: 16px;
        border: 2px solid var(--color-border);
        border-top-color: var(--color-primary);
        border-radius: 50%;
        animation: location-spinner 0.8s linear infinite;
    }

    @keyframes location-spinner {
        to { transform: translateY(-50%) rotate(360deg); }
    }

    location-picker .suggestions-dropdown {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--color-bg);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-lg);
        z-index: 100;
        max-height: 280px;
        overflow-y: auto;
        display: none;
        margin-top: 4px;
    }

    location-picker .suggestions-dropdown.open {
        display: block;
    }

    location-picker .suggestion-item {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-md);
        cursor: pointer;
        transition: background-color var(--transition-fast);
    }

    location-picker .suggestion-item:hover,
    location-picker .suggestion-item.focused {
        background: var(--color-bg-secondary);
    }

    location-picker .suggestion-icon {
        flex-shrink: 0;
        font-size: 1rem;
    }

    location-picker .suggestion-text {
        display: flex;
        flex-direction: column;
        min-width: 0;
    }

    location-picker .suggestion-name {
        font-size: var(--font-size-sm);
        font-weight: var(--font-weight-medium);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    location-picker .suggestion-detail {
        font-size: var(--font-size-xs);
        color: var(--color-text-muted);
    }
`
document.head.appendChild(style)

export { LocationPicker }
