import { t, i18n } from '../../i18n.js'
import { listingsService } from '../../services/listings.js'
import { directus } from '../../services/directus.js'
import { locationsService } from '../../services/locations.js'
import { auth } from '../../services/auth.js'
import { escapeHTML } from '../../utils/helpers.js'
import '../listing-card.js'
import '../skeleton-card.js'
import '../search-box.js'

class PageHome extends HTMLElement {
    constructor() {
        super()
        this.listings = []
        this.loading = false
        this.loadingMore = false
        this.error = null
        this.page = 1
        this.hasMore = true
        
        // Filter state
        this.query = ''
        this.category = ''
        this.subcategory = ''
        this.sort = 'newest'
        this.minPrice = null
        this.maxPrice = null
        this.priceFilterOpen = false
        
        // Geo state
        this.userLat = null
        this.userLng = null

        this._onHashChange = this.handleHashChange.bind(this)
    }

    connectedCallback() {
        this.parseUrlParams()
        this.render()
        this.setupEventListeners()
        this.setupPullToRefresh()
        this.loadListings()
        this.unsubscribe = i18n.subscribe(() => {
            this.updateTextContent()
        })
        
        // Re-render listings on auth change to show owner badges
        this.authUnsubscribe = auth.subscribe(() => {
            const container = this.querySelector('#listings-container')
            if (container) {
                container.innerHTML = this.renderListings()
            }
        })

        // Listen for URL changes (back/forward navigation)
        window.addEventListener('hashchange', this._onHashChange)
    }

    disconnectedCallback() {
        if (this.unsubscribe) this.unsubscribe()
        if (this.authUnsubscribe) this.authUnsubscribe()
        window.removeEventListener('hashchange', this._onHashChange)
    }

    handleHashChange() {
        const hash = window.location.hash
        if (hash === '#/' || hash.startsWith('#/?')) {
            this.parseUrlParams()
            this.resetAndSearch()
        }
    }

    parseUrlParams() {
        const params = new URLSearchParams(window.location.hash.split('?')[1] || '')
        this.query = params.get('q') || ''
        this.category = params.get('category') || ''
        this.sort = params.get('sort') || 'newest'
        this.minPrice = params.get('min') ? parseFloat(params.get('min')) : null
        this.maxPrice = params.get('max') ? parseFloat(params.get('max')) : null
    }

    updateUrl() {
        const params = new URLSearchParams()
        if (this.query) params.set('q', this.query)
        if (this.category) params.set('category', this.category)
        if (this.sort !== 'newest') params.set('sort', this.sort)
        if (this.minPrice) params.set('min', this.minPrice)
        if (this.maxPrice) params.set('max', this.maxPrice)
        
        const paramString = params.toString()
        const newHash = paramString ? `#/?${paramString}` : '#/'
        
        if (window.location.hash !== newHash) {
            history.replaceState(null, '', newHash)
        }
    }

    hasActiveFilters() {
        return this.query || this.category || this.minPrice || this.maxPrice || this.sort !== 'newest'
    }

    hasUserLocation() {
        return this.userLat != null && this.userLng != null
    }

    updateUserLocation(detail) {
        if (detail.useCurrentLocation && detail.lat && detail.lng) {
            this.userLat = detail.lat
            this.userLng = detail.lng
        } else {
            this.userLat = null
            this.userLng = null
            // If sorting by distance but no location, reset sort
            if (this.sort === 'distance') {
                this.sort = 'newest'
            }
        }
    }

    resetAndSearch() {
        this.page = 1
        this.listings = []
        this.hasMore = true
        this.loadListings()
    }

    setupEventListeners() {
        const searchBox = this.querySelector('search-box')
        
        searchBox?.addEventListener('filter-change', (e) => {
            const hadLocation = this.hasUserLocation()
            this.category = e.detail.category || ''
            this.subcategory = e.detail.subcategory || ''
            this.query = e.detail.query || ''
            this.updateUserLocation(e.detail)
            this.updateUrl()
            
            // Re-render if location status changed (to show/hide distance sort)
            if (hadLocation !== this.hasUserLocation()) {
                this.render()
                this.setupEventListeners()
            }
            
            this.resetAndSearch()
        })

        searchBox?.addEventListener('search', (e) => {
            e.preventDefault()
            e.stopPropagation()
            this.query = e.detail.query || ''
            this.category = e.detail.category || ''
            this.subcategory = e.detail.subcategory || ''
            this.updateUserLocation(e.detail)
            this.updateUrl()
            this.resetAndSearch()
            return false
        })

        // Toggle price filter
        this.querySelector('#toggle-price-filter')?.addEventListener('click', () => {
            this.togglePriceFilter()
        })

        // Sort change
        this.querySelector('#sort-select')?.addEventListener('change', (e) => {
            this.sort = e.target.value
            this.updateUrl()
            this.resetAndSearch()
        })

        // Price filter
        this.querySelector('#apply-price')?.addEventListener('click', () => {
            this.minPrice = parseFloat(this.querySelector('#min-price')?.value) || null
            this.maxPrice = parseFloat(this.querySelector('#max-price')?.value) || null
            this.updateUrl()
            this.resetAndSearch()
        })

        // Enter key on price inputs
        this.querySelectorAll('#min-price, #max-price').forEach(input => {
            input.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    this.minPrice = parseFloat(this.querySelector('#min-price')?.value) || null
                    this.maxPrice = parseFloat(this.querySelector('#max-price')?.value) || null
                    this.updateUrl()
                    this.resetAndSearch()
                }
            })
        })

        // Clear filters
        this.querySelector('#clear-filters')?.addEventListener('click', () => {
            this.query = ''
            this.category = ''
            this.subcategory = ''
            this.sort = 'newest'
            this.minPrice = null
            this.maxPrice = null
            this.priceFilterOpen = false
            this.updateUrl()
            this.render()
            this.setupEventListeners()
            this.resetAndSearch()
        })
    }

    async loadListings() {
        if (this.page === 1) {
            this.loading = true
        } else {
            this.loadingMore = true
        }
        this.error = null
        this.updateListingsSection()

        try {
            // For distance sort, we need to load more items and sort client-side
            const isDistanceSort = this.sort === 'distance' && this.hasUserLocation()
            
            const filters = {
                search: this.query || undefined,
                category: this.category || undefined,
                subcategory: this.subcategory || undefined,
                sort: isDistanceSort ? 'newest' : this.sort, // Backend can't sort by distance
                minPrice: this.minPrice,
                maxPrice: this.maxPrice,
                limit: isDistanceSort ? 100 : 20, // Load more for client-side sorting
                page: isDistanceSort ? 1 : this.page
            }

            const response = await listingsService.getListingsWithFilters(filters)
            let newItems = response.items || []
            
            // Client-side distance sorting
            if (isDistanceSort) {
                newItems = this.sortByDistance(newItems)
                // Paginate client-side
                const start = (this.page - 1) * 20
                const end = start + 20
                newItems = newItems.slice(start, end)
            }
            
            if (this.page === 1) {
                this.listings = newItems
            } else {
                this.listings = [...this.listings, ...newItems]
            }
            
            this.hasMore = newItems.length === 20
            this.loading = false
            this.loadingMore = false
            this.updateListingsSection()
            this.setupLoadMoreButton()
        } catch (err) {
            console.error('Failed to load listings:', err)
            this.error = err.message
            this.loading = false
            this.loadingMore = false
            this.updateListingsSection()
        }
    }

    sortByDistance(listings) {
        if (!this.hasUserLocation()) return listings
        
        return listings
            .map(listing => {
                const lat = listing.location?.latitude
                const lng = listing.location?.longitude
                if (lat && lng) {
                    listing._distance = locationsService.calculateDistance(
                        this.userLat, this.userLng, lat, lng
                    )
                } else {
                    listing._distance = Infinity
                }
                return listing
            })
            .sort((a, b) => a._distance - b._distance)
    }

    setupLoadMoreButton() {
        const btn = this.querySelector('#load-more-btn')
        btn?.addEventListener('click', () => {
            this.page++
            this.loadListings()
        })
    }

    setupPullToRefresh() {
        let startY = 0
        let pulling = false
        const threshold = 80
        
        const indicator = document.createElement('div')
        indicator.className = 'pull-indicator'
        indicator.innerHTML = `<div class="pull-spinner"></div><span>${t('home.pullToRefresh')}</span>`
        this.prepend(indicator)

        this.addEventListener('touchstart', (e) => {
            if (window.scrollY === 0) {
                startY = e.touches[0].clientY
                pulling = true
            }
        }, { passive: true })

        this.addEventListener('touchmove', (e) => {
            if (!pulling) return
            
            const currentY = e.touches[0].clientY
            const diff = currentY - startY
            
            if (diff > 0 && diff < threshold * 2) {
                indicator.style.transform = `translateY(${Math.min(diff / 2, threshold)}px)`
                indicator.style.opacity = Math.min(diff / threshold, 1)
                
                if (diff > threshold) {
                    indicator.classList.add('ready')
                } else {
                    indicator.classList.remove('ready')
                }
            }
        }, { passive: true })

        this.addEventListener('touchend', () => {
            if (!pulling) return
            pulling = false
            
            if (indicator.classList.contains('ready')) {
                indicator.classList.add('refreshing')
                indicator.classList.remove('ready')
                
                // Refresh
                this.page = 1
                this.listings = []
                this.hasMore = true
                this.loadListings().then(() => {
                    indicator.classList.remove('refreshing')
                    indicator.style.transform = ''
                    indicator.style.opacity = ''
                })
            } else {
                indicator.style.transform = ''
                indicator.style.opacity = ''
            }
        }, { passive: true })
    }

    updateListingsSection() {
        const listingsContainer = this.querySelector('#listings-container')
        if (listingsContainer) {
            listingsContainer.innerHTML = this.renderListings()
            this.setupLoadMoreButton()
        }
        
        const titleEl = this.querySelector('.listings-title')
        if (titleEl) {
            titleEl.textContent = this.getListingsTitle()
        }
    }

    updateTextContent() {
        const titleEl = this.querySelector('.listings-title')
        if (titleEl) titleEl.textContent = this.getListingsTitle()

        const sortSelect = this.querySelector('#sort-select')
        if (sortSelect) {
            sortSelect.querySelectorAll('option').forEach(opt => {
                const key = {
                    distance: 'search.sortDistance',
                    newest: 'search.sortNewest',
                    oldest: 'search.sortOldest',
                    price_asc: 'search.sortPriceAsc',
                    price_desc: 'search.sortPriceDesc'
                }[opt.value]
                if (key) opt.textContent = t(key)
            })
        }

        const priceBtn = this.querySelector('#toggle-price-filter span')
        if (priceBtn) priceBtn.textContent = t('search.priceRange')

        const clearBtn = this.querySelector('#clear-filters')
        if (clearBtn) clearBtn.textContent = t('search.clearAll')

        const applyBtn = this.querySelector('#apply-price')
        if (applyBtn) applyBtn.textContent = t('search.apply')

        const minInput = this.querySelector('#min-price')
        if (minInput) minInput.placeholder = t('search.min')

        const maxInput = this.querySelector('#max-price')
        if (maxInput) maxInput.placeholder = t('search.max')

        const searchBox = this.querySelector('search-box')
        if (searchBox) searchBox.loadAndRender()
    }

    getListingsTitle() {
        if (this.hasActiveFilters()) {
            const count = this.listings.length
            return t('search.resultsCount', { count }) || `${count} Ergebnisse`
        }
        return t('home.recentListings')
    }

    render() {
        const showFilters = this.hasActiveFilters()
        const hasPriceFilter = this.minPrice || this.maxPrice
        
        this.innerHTML = /* html */`
            <section class="search-section">
                <search-box no-navigate></search-box>
            </section>
            
            <section class="listings-section">
                <div class="listings-header">
                    ${showFilters ? `<h2 class="listings-title">${this.getListingsTitle()}</h2>` : ''}
                    <div class="listings-toolbar">
                        <div class="sort-inline">
                            <select id="sort-select">
                                ${this.hasUserLocation() ? `<option value="distance" ${this.sort === 'distance' ? 'selected' : ''}>${t('search.sortDistance')}</option>` : ''}
                                <option value="newest" ${this.sort === 'newest' ? 'selected' : ''}>${t('search.sortNewest')}</option>
                                <option value="oldest" ${this.sort === 'oldest' ? 'selected' : ''}>${t('search.sortOldest')}</option>
                                <option value="price_asc" ${this.sort === 'price_asc' ? 'selected' : ''}>${t('search.sortPriceAsc')}</option>
                                <option value="price_desc" ${this.sort === 'price_desc' ? 'selected' : ''}>${t('search.sortPriceDesc')}</option>
                            </select>
                        </div>
                        <button class="btn btn-sm btn-outline" id="toggle-price-filter">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="4" y1="21" x2="4" y2="14"></line>
                                <line x1="4" y1="10" x2="4" y2="3"></line>
                                <line x1="12" y1="21" x2="12" y2="12"></line>
                                <line x1="12" y1="8" x2="12" y2="3"></line>
                                <line x1="20" y1="21" x2="20" y2="16"></line>
                                <line x1="20" y1="12" x2="20" y2="3"></line>
                                <line x1="1" y1="14" x2="7" y2="14"></line>
                                <line x1="9" y1="8" x2="15" y2="8"></line>
                                <line x1="17" y1="16" x2="23" y2="16"></line>
                            </svg>
                            <span>${t('search.priceRange')}</span>
                            ${hasPriceFilter ? '<span class="filter-active-dot"></span>' : ''}
                        </button>
                        ${showFilters ? `
                            <button class="btn btn-sm btn-ghost" id="clear-filters">${t('search.clearAll')}</button>
                        ` : ''}
                    </div>
                </div>
                <div class="price-filter-panel ${this.priceFilterOpen ? 'open' : ''}" id="price-filter-panel">
                    <div class="price-inputs">
                        <input type="number" id="min-price" placeholder="${t('search.min')}" 
                            value="${this.minPrice || ''}" min="0" step="1">
                        <span class="price-separator">–</span>
                        <input type="number" id="max-price" placeholder="${t('search.max')}" 
                            value="${this.maxPrice || ''}" min="0" step="1">
                        <button class="btn btn-sm btn-primary" id="apply-price">${t('search.apply')}</button>
                    </div>
                </div>
                <div id="listings-container" class="listings-grid">
                    ${this.renderListings()}
                </div>
            </section>
        `
        
        // Sync search-box with current filters
        const searchBox = this.querySelector('search-box')
        if (searchBox) {
            searchBox.setFilters({
                query: this.query,
                category: this.category
            })
        }
    }

    togglePriceFilter() {
        this.priceFilterOpen = !this.priceFilterOpen
        const panel = this.querySelector('#price-filter-panel')
        if (panel) panel.classList.toggle('open', this.priceFilterOpen)
    }

    renderListings() {
        if (this.loading) {
            // Show skeleton cards while loading
            return Array(8).fill(0).map(() => '<skeleton-card></skeleton-card>').join('')
        }

        if (this.error) {
            return /* html */`
                <div class="empty-state">
                    <div class="empty-icon">⚠️</div>
                    <p>${t('common.error')}</p>
                </div>
            `
        }

        if (this.listings.length === 0) {
            return /* html */`
                <div class="empty-state">
                    <div class="empty-icon">${this.hasActiveFilters() ? '😕' : '📦'}</div>
                    <p>${this.hasActiveFilters() ? t('search.noResults') : t('home.noListings')}</p>
                </div>
            `
        }

        const listingsHtml = this.listings.map(listing => {
            const imageId = listing.images?.[0]?.directus_files_id?.id || listing.images?.[0]?.directus_files_id
            const imageUrl = imageId ? directus.getThumbnailUrl(imageId, 300) : ''
            const locationName = listing.location?.name || ''

            return /* html */`
                <listing-card 
                    listing-id="${listing.id}"
                    title="${escapeHTML(listing.title || '')}"
                    price="${listing.price || ''}"
                    currency="${listing.currency || 'EUR'}"
                    location="${escapeHTML(locationName)}"
                    image="${imageUrl}"
                    owner-id="${listing.user_created || ''}"
                ></listing-card>
            `
        }).join('')

        const loadMoreHtml = this.hasMore ? `
            <div class="load-more-container">
                ${this.loadingMore ? `
                    <div class="spinner"></div>
                    <p>${t('common.loading')}</p>
                ` : `
                    <button id="load-more-btn" class="btn btn-outline">
                        ${t('home.loadMore')}
                    </button>
                `}
            </div>
        ` : ''

        return listingsHtml + loadMoreHtml
    }
}

customElements.define('page-home', PageHome)

const style = document.createElement('style')
style.textContent = /* css */`
    /* Search Section */
    page-home .search-section {
        padding: var(--space-xl) 0 var(--space-lg);
    }
    
    /* Toolbar */
    page-home .listings-toolbar {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        flex-wrap: wrap;
    }

    page-home .sort-inline select {
        padding: var(--space-xs) var(--space-sm);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-sm);
        background: var(--color-bg);
        color: var(--color-text);
        font-size: var(--font-size-sm);
        min-width: 150px;
    }

    page-home .btn-sm {
        padding: var(--space-xs) var(--space-sm);
        font-size: var(--font-size-sm);
    }

    page-home .btn-ghost {
        background: transparent;
        border: none;
        color: var(--color-text-muted);
        cursor: pointer;
    }

    page-home .btn-ghost:hover {
        color: var(--color-text);
    }

    page-home .filter-active-dot {
        width: 6px;
        height: 6px;
        border-radius: var(--radius-full);
        background: var(--color-accent);
        display: inline-block;
    }

    /* Price Filter Panel */
    page-home .price-filter-panel {
        display: none;
        padding: var(--space-md);
        margin-bottom: var(--space-md);
        background: var(--color-bg-secondary);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
    }

    page-home .price-filter-panel.open {
        display: block;
    }

    page-home .price-inputs {
        display: flex;
        align-items: center;
        gap: var(--space-md);
    }

    page-home .price-inputs input {
        width: 100px;
        padding: var(--space-xs) var(--space-sm);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-sm);
        background: var(--color-bg);
        color: var(--color-text);
        font-size: var(--font-size-sm);
    }

    page-home .price-separator {
        color: var(--color-text-muted);
    }

    @media (max-width: 768px) {
        page-home .listings-toolbar {
            width: 100%;
        }

        page-home .sort-inline {
            flex: 1;
        }

        page-home .sort-inline select {
            width: 100%;
            min-width: 0;
        }

        page-home .price-inputs {
            flex-wrap: wrap;
        }

        page-home .price-inputs input {
            flex: 1;
            min-width: 0;
            width: auto;
        }

        page-home .price-inputs .btn {
            width: 100%;
        }
    }
    
    /* Listings Section */
    page-home .listings-section {
        margin-bottom: var(--space-xl);
    }
    
    page-home .listings-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: var(--space-lg);
        flex-wrap: wrap;
        gap: var(--space-sm);
    }
    
    page-home .listings-title {
        margin: 0;
    }

    page-home .loading-state,
    page-home .empty-state {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: var(--space-2xl);
        color: var(--color-text-muted);
        grid-column: 1 / -1;
    }
    
    page-home .empty-icon {
        font-size: 3rem;
        margin-bottom: var(--space-md);
        filter: grayscale(1);
    }
    
    page-home .spinner {
        width: 40px;
        height: 40px;
        border: 3px solid var(--color-border);
        border-top-color: var(--color-primary);
        border-radius: 50%;
        animation: spin 1s linear infinite;
        margin-bottom: var(--space-md);
    }
    
    @keyframes spin {
        to { transform: rotate(360deg); }
    }
    
    page-home .load-more-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: var(--space-xl);
        color: var(--color-text-muted);
        grid-column: 1 / -1;
    }
    
    page-home .load-more-container .spinner {
        width: 30px;
        height: 30px;
        margin-bottom: var(--space-sm);
    }
    
    /* Pull to Refresh */
    page-home .pull-indicator {
        position: absolute;
        top: 0;
        left: 50%;
        transform: translateX(-50%) translateY(-60px);
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-md);
        background: var(--color-bg-secondary);
        border: 1px solid var(--color-border);
        border-radius: var(--radius-full);
        opacity: 0;
        transition: opacity 0.2s ease;
        z-index: 100;
        font-size: var(--font-size-sm);
        color: var(--color-text-muted);
    }
    
    page-home .pull-indicator.ready {
        color: var(--color-primary);
    }
    
    page-home .pull-indicator.ready span::after {
        content: ' ↓';
    }
    
    page-home .pull-spinner {
        width: 16px;
        height: 16px;
        border: 2px solid var(--color-border);
        border-top-color: var(--color-primary);
        border-radius: 50%;
    }
    
    page-home .pull-indicator.refreshing .pull-spinner {
        animation: spin 1s linear infinite;
    }
`
document.head.appendChild(style)
