/**
 * Locations Service - Handles location data and geosearch
 */

import { directus } from './directus.js'

class LocationsService {
    constructor() {
        this.cache = new Map()
        this.cacheTimeout = 30 * 60 * 1000 // 30 minutes
    }

    async getAll() {
        const cacheKey = 'all_locations'
        const cached = this.getFromCache(cacheKey)
        if (cached) return cached

        const locations = await directus.getLocations()
        this.setCache(cacheKey, locations)
        return locations
    }

    async getById(id) {
        return directus.getLocation(id)
    }

    async search(query) {
        if (!query || query.length < 2) return []
        return directus.searchLocations(query)
    }

    async getByRegion(region) {
        const cacheKey = `region_${region}`
        const cached = this.getFromCache(cacheKey)
        if (cached) return cached

        const locations = await directus.getLocationsByRegion(region)
        this.setCache(cacheKey, locations)
        return locations
    }

    async getByCountry(country) {
        const cacheKey = `country_${country}`
        const cached = this.getFromCache(cacheKey)
        if (cached) return cached

        const locations = await directus.getLocationsByCountry(country)
        this.setCache(cacheKey, locations)
        return locations
    }

    async getRegions(country = 'DE') {
        const locations = await this.getByCountry(country)
        const regions = [...new Set(locations.map(l => l.region).filter(Boolean))]
        return regions.sort()
    }

    async getNearby(latitude, longitude, radiusKm = 50, limit = 10) {
        const locations = await this.getAll()
        
        const withDistance = locations
            .filter(loc => loc.latitude && loc.longitude)
            .map(loc => ({
                ...loc,
                distance: this.calculateDistance(latitude, longitude, loc.latitude, loc.longitude)
            }))
            .filter(loc => loc.distance <= radiusKm)
            .sort((a, b) => a.distance - b.distance)
            .slice(0, limit)

        return withDistance
    }

    calculateDistance(lat1, lon1, lat2, lon2) {
        const R = 6371 // Earth radius in km
        const dLat = this.toRad(lat2 - lat1)
        const dLon = this.toRad(lon2 - lon1)
        const a = 
            Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(this.toRad(lat1)) * Math.cos(this.toRad(lat2)) * 
            Math.sin(dLon / 2) * Math.sin(dLon / 2)
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
        return R * c
    }

    toRad(deg) {
        return deg * (Math.PI / 180)
    }

    formatLocation(location) {
        if (!location) return ''
        
        const parts = [location.name]
        if (location.postal_code) parts.unshift(location.postal_code)
        if (location.region && location.region !== location.name) {
            parts.push(location.region)
        }
        
        return parts.join(', ')
    }

    formatDistance(distanceKm) {
        if (distanceKm < 1) {
            return `${Math.round(distanceKm * 1000)} m`
        }
        return `${distanceKm.toFixed(1)} km`
    }

    async getCurrentLocation() {
        return new Promise((resolve, reject) => {
            if (!navigator.geolocation) {
                reject(new Error('Geolocation not supported'))
                return
            }

            navigator.geolocation.getCurrentPosition(
                pos => resolve({
                    latitude: pos.coords.latitude,
                    longitude: pos.coords.longitude,
                    accuracy: pos.coords.accuracy
                }),
                err => reject(err),
                { enableHighAccuracy: false, timeout: 10000 }
            )
        })
    }

    async findNearestLocation() {
        try {
            const coords = await this.getCurrentLocation()
            const nearby = await this.getNearby(coords.latitude, coords.longitude, 100, 1)
            return nearby[0] || null
        } catch (e) {
            console.warn('Could not get location:', e)
            return null
        }
    }

    getFromCache(key) {
        const cached = this.cache.get(key)
        if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
            return cached.data
        }
        return null
    }

    setCache(key, data) {
        this.cache.set(key, { data, timestamp: Date.now() })
    }

    clearCache() {
        this.cache.clear()
    }
}

export const locationsService = new LocationsService()
