/**
 * Categories Service - Handles category tree and translations
 */

import { directus } from './directus.js'
import { getCurrentLanguage, LOCALE_TO_DIRECTUS } from '../i18n.js'

class CategoriesService {
    constructor() {
        this.cache = null
        this.cacheTimestamp = 0
        this.cacheTimeout = 24 * 60 * 60 * 1000 // 24 hours
        this.storageKey = 'dgray_categories'
        this.storageTimestampKey = 'dgray_categories_ts'
        this._pending = null
        this._loadFromStorage()
    }

    _loadFromStorage() {
        try {
            const data = localStorage.getItem(this.storageKey)
            const ts = parseInt(localStorage.getItem(this.storageTimestampKey) || '0', 10)
            if (data && ts && Date.now() - ts < this.cacheTimeout) {
                this.cache = JSON.parse(data)
                this.cacheTimestamp = ts
            }
        } catch (e) {
            // ignore corrupt storage
        }
    }

    _saveToStorage() {
        try {
            localStorage.setItem(this.storageKey, JSON.stringify(this.cache))
            localStorage.setItem(this.storageTimestampKey, String(this.cacheTimestamp))
        } catch (e) {
            // storage full or unavailable
        }
    }

    async getAll() {
        if (this.cache && Date.now() - this.cacheTimestamp < this.cacheTimeout) {
            return this.cache
        }

        if (this._pending) return this._pending

        this._pending = directus.getCategories().then(categories => {
            this.cache = categories
            this.cacheTimestamp = Date.now()
            this._saveToStorage()
            this._pending = null
            return categories
        }).catch(err => {
            this._pending = null
            throw err
        })

        return this._pending
    }

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

    async getBySlug(slug) {
        return directus.getCategory(slug)
    }

    async getTree() {
        const all = await this.getAll()
        return this.buildTree(all)
    }

    buildTree(categories, parentId = null) {
        return categories
            .filter(cat => (cat.parent?.id || cat.parent) === parentId)
            .map(cat => ({
                ...cat,
                children: this.buildTree(categories, cat.id)
            }))
    }

    async getSubcategories(parentId) {
        return directus.getSubcategories(parentId)
    }

    async getRootCategories() {
        const all = await this.getAll()
        return all.filter(cat => !cat.parent)
    }

    async getCategoryPath(categoryId) {
        const all = await this.getAll()
        const path = []
        let current = all.find(c => c.id === categoryId)
        
        while (current) {
            path.unshift(current)
            const parentId = current.parent?.id || current.parent
            current = parentId ? all.find(c => c.id === parentId) : null
        }
        
        return path
    }

    async getCategoryWithChildren(categoryId) {
        const all = await this.getAll()
        const category = all.find(c => c.id === categoryId)
        if (!category) return null

        const collectChildren = (parentId) => {
            return all
                .filter(c => (c.parent?.id || c.parent) === parentId)
                .map(c => ({
                    ...c,
                    children: collectChildren(c.id)
                }))
        }

        return {
            ...category,
            children: collectChildren(categoryId)
        }
    }

    getTranslatedName(category, lang = null) {
        const currentLang = lang || getCurrentLanguage()
        const directusCode = LOCALE_TO_DIRECTUS[currentLang] || currentLang
        
        if (category.translations && Array.isArray(category.translations)) {
            const translation = category.translations.find(
                t => t.languages_code === directusCode
                    || t.languages_code === currentLang
                    || t.languages_code?.startsWith(currentLang)
            )
            if (translation?.name) {
                return translation.name
            }
        }
        
        return category.name
    }

    formatCategoryPath(categories, lang = null) {
        return categories
            .map(cat => this.getTranslatedName(cat, lang))
            .join(' › ')
    }

    async searchCategories(query) {
        if (!query || query.length < 2) return []
        
        const all = await this.getAll()
        const lowerQuery = query.toLowerCase()
        
        return all.filter(cat => {
            if (cat.name?.toLowerCase().includes(lowerQuery)) return true
            if (cat.slug?.toLowerCase().includes(lowerQuery)) return true
            
            if (cat.translations) {
                return cat.translations.some(t => 
                    t.name?.toLowerCase().includes(lowerQuery)
                )
            }
            
            return false
        })
    }

    async getCategoriesForSelect(includeChildren = true) {
        const tree = await this.getTree()
        const options = []
        
        const flatten = (categories, depth = 0) => {
            for (const cat of categories) {
                options.push({
                    id: cat.id,
                    name: this.getTranslatedName(cat),
                    slug: cat.slug,
                    icon: cat.icon,
                    depth,
                    label: '  '.repeat(depth) + this.getTranslatedName(cat)
                })
                
                if (includeChildren && cat.children?.length > 0) {
                    flatten(cat.children, depth + 1)
                }
            }
        }
        
        flatten(tree)
        return options
    }

    clearCache() {
        this.cache = null
        this.cacheTimestamp = 0
        localStorage.removeItem(this.storageKey)
        localStorage.removeItem(this.storageTimestampKey)
    }
}

export const categoriesService = new CategoriesService()
