# обязательно подключение глобальных массивов
globalThis.renderFns = require 'pug.json'
globalThis.stylFns   = require 'styl.json'

# подключение мета информации (строго в данном фиде)
document.head.insertAdjacentHTML 'beforeend','<meta charset="UTF-8">'
document.head.insertAdjacentHTML 'beforeend','<meta name="viewport" content="width=device-width, initial-scale=1.0">'
document.head.insertAdjacentHTML('beforeend','<title> Кохи Борбад - Концертный зал Душанбе</title>')

# Настройка tailwind
tailwind.config = require 'tailwind.config.js'

# подключение основных стилей
## tailwind
document.head.insertAdjacentHTML('beforeend','<style  type="text/tailwindcss"  page="main">'+stylFns['main.css']+'</style>')
## базовой стиль приложения
document.head.insertAdjacentHTML('beforeend','<style  type="text/tailwindcss"  page="root">'+stylFns['app/temp.styl']+'</style>')

# Создаем глобальную шину событий
class AppEventBus
    constructor: ->
        @events = {}
    
    on: (event, callback) ->
        if !@events[event]
            @events[event] = []
        @events[event].push(callback)
    
    emit: (event, data) ->
        if @events[event]
            for callback in @events[event]
                try
                    callback(data)
                catch error
                    debug.log "Event bus error: " + error
    
    off: (event, callback) ->
        if @events[event]
            @events[event] = @events[event].filter (cb) -> cb != callback

# Создаем глобально
globalThis.EventBus = new AppEventBus()

# Класс для работы с мультиязычными данными
class MultilingualData
    constructor: ->
        @currentLanguage = 'ru'
        @availableLanguages = ['ru', 'en', 'tj']
        @fallbackLanguage = 'ru'
    
    # Установка текущего языка
    setLanguage: (language) ->
        if language in @availableLanguages
            @currentLanguage = language
            EventBus.emit('language_changed', language)
            debug.log "Язык изменен на: "+language
    
    # Получение текста для текущего языка
    getText: (textArray, fallback = '') ->
        if not textArray or not Array.isArray(textArray)
            return fallback
        
        languageIndex = @availableLanguages.indexOf(@currentLanguage)
        if languageIndex is -1 or languageIndex >= textArray.length
            languageIndex = @availableLanguages.indexOf(@fallbackLanguage)
        
        return textArray[languageIndex] or fallback
    
    # Получение всех текстов для отладки
    getAllTexts: (textArray) ->
        if not textArray or not Array.isArray(textArray)
            return {}
        
        result = {}
        for lang, index in @availableLanguages
            if textArray[index]
                result[lang] = textArray[index]
        return result

# Класс для работы с базой данных
class AppDatabase
    constructor: ->
        @db = null
        @baseUrl = 'https://oleg:631074@couchdb.favt.ru.net'
        @dbName = 'borbad_events'
        @initialized = false
        @multilingual = new MultilingualData()
    
    # Инициализация базы данных
    initialize: ->
        try
            PouchDB = require 'pouchdb'
            @db = new PouchDB(@baseUrl+"/"+@dbName)
            
            # Проверяем соединение
            info = await @db.info()
            debug.log "База данных подключена: "+info.db_name
            
            @initialized = true
            EventBus.emit('database_ready', @db)
            
        catch error
            debug.log "Ошибка подключения к базе данных: "+error
            EventBus.emit('database_error', error)
    
    # Получение документов по типу с мультиязычной обработкой
    getDocumentsByType: (type, options = {}) ->
        if not @initialized
            throw new Error("База данных не инициализирована")
        
        try
            viewName = options.view or 'published_by_domain_language'
            designDoc = options.designDoc or 'multilingual_content'
            
            result = await @db.query(designDoc+'/'+viewName, {
                startkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage]
                endkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage, {}]
                include_docs: true
                descending: options.descending or true
                limit: options.limit or 10
                skip: options.skip or 0
            })
            
            # Обрабатываем мультиязычные данные
            processedDocs = result.rows.map (row) =>
                @processMultilingualDocument(row.doc)
            
            return processedDocs
            
        catch error
            debug.log "Ошибка получения документов типа "+type+": "+error
            return []
    
    # Обработка мультиязычного документа
    processMultilingualDocument: (doc) ->
        if not doc
            return null
        
        processedDoc = Object.assign({}, doc)
        
        # Обрабатываем мультиязычные поля
        multilingualFields = ['title', 'content', 'excerpt', 'author', 'name', 'description', 'location']
        
        for field in multilingualFields
            if doc[field] and Array.isArray(doc[field])
                processedDoc[field] = @multilingual.getText(doc[field])
        
        # Обрабатываем вложенные мультиязычные структуры
        if doc.seo
            processedDoc.seo = {}
            if doc.seo.description and Array.isArray(doc.seo.description)
                processedDoc.seo.description = @multilingual.getText(doc.seo.description)
            if doc.seo.title and Array.isArray(doc.seo.title)
                processedDoc.seo.title = @multilingual.getText(doc.seo.title)
            if doc.seo.keywords and Array.isArray(doc.seo.keywords)
                processedDoc.seo.keywords = @multilingual.getText(doc.seo.keywords, [])
        
        # Обрабатываем специфичные данные для разных типов
        if doc.type is 'event' and doc.event_data
            processedDoc.event_data = Object.assign({}, doc.event_data)
            if doc.event_data.location and Array.isArray(doc.event_data.location)
                processedDoc.event_data.location = @multilingual.getText(doc.event_data.location)
            if doc.event_data.price and Array.isArray(doc.event_data.price)
                processedDoc.event_data.price = @multilingual.getText(doc.event_data.price)
        
        if doc.type is 'product' and doc.product_data
            processedDoc.product_data = Object.assign({}, doc.product_data)
            if doc.product_data.price and Array.isArray(doc.product_data.price)
                processedDoc.product_data.price = @multilingual.getText(doc.product_data.price)
        
        if doc.type is 'slide' and doc.slide_data
            processedDoc.slide_data = Object.assign({}, doc.slide_data)
            if doc.slide_data.button_text and Array.isArray(doc.slide_data.button_text)
                processedDoc.slide_data.button_text = @multilingual.getText(doc.slide_data.button_text)
            if doc.slide_data.button_link and Array.isArray(doc.slide_data.button_link)
                processedDoc.slide_data.button_link = @multilingual.getText(doc.slide_data.button_link)
        
        return processedDoc
    
    # Получение блог постов
    getBlogPosts: (options = {}) ->
        options.type = 'blog_post'
        return await @getDocumentsByType('blog_post', options)
    
    # Получение мероприятий
    getEvents: (options = {}) ->
        options.type = 'event'
        options.view = 'by_date_multilingual'
        return await @getDocumentsByType('event', options)
    
    # Получение предстоящих мероприятий
    getUpcomingEvents: (options = {}) ->
        options.type = 'event'
        options.view = 'upcoming_events'
        return await @getDocumentsByType('event', options)
    
    # Получение товаров
    getProducts: (options = {}) ->
        options.type = 'product'
        options.view = 'by_status_multilingual'
        return await @getDocumentsByType('product', options)
    
    # Получение слайдов
    getSlides: (options = {}) ->
        options.type = 'slide'
        options.view = 'active_ordered_multilingual'
        options.descending = false
        return await @getDocumentsByType('slide', options)
    
    # Получение категорий
    getCategories: (options = {}) ->
        if not @initialized
            throw new Error("База данных не инициализирована")
        
        try
            result = await @db.query('categories_hierarchical_multilingual/by_level_multilingual', {
                startkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage, 0]
                endkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage, 0, {}]
                include_docs: true
                ascending: true
            })
            
            processedCategories = result.rows.map (row) =>
                @processMultilingualDocument(row.doc)
            
            return processedCategories
            
        catch error
            debug.log "Ошибка получения категорий: "+error
            return []
    
    # Поиск по контенту
    searchContent: (query, options = {}) ->
        if not @initialized
            throw new Error("База данных не инициализирована")
        
        try
            result = await @db.query('universal_multilingual_search/content_search', {
                startkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage, query.toLowerCase()]
                endkey: [options.domain or 'borbad.s5l.ru', @multilingual.currentLanguage, query.toLowerCase() + "\ufff0"]
                include_docs: true
                limit: options.limit or 20
            })
            
            processedResults = result.rows.map (row) =>
                @processMultilingualDocument(row.doc)
            
            return processedResults
            
        catch error
            debug.log "Ошибка поиска: "+error
            return []
    
    # Получение документа по ID
    getDocumentById: (id) ->
        if not @initialized
            throw new Error("База данных не инициализирована")
        
        try
            doc = await @db.get(id)
            return @processMultilingualDocument(doc)
        catch error
            debug.log "Ошибка получения документа "+id+": "+error
            return null

# Создаем глобальные экземпляры
globalThis.AppDB = new AppDatabase()
globalThis.Multilingual = new MultilingualData()

# Маршруты
routes = [
  { path: '/', component: require 'app/pages/Home' }
  { path: '/events', component: require 'app/pages/Events' }
  { path: '/events/:id', component: require 'app/pages/EventDetail' }
#  { path: '/blog', component: require 'app/pages/Blog' }
#  { path: '/blog/:id', component: require 'app/pages/BlogDetail' }
#  { path: '/products', component: require 'app/pages/Products' }
#  { path: '/products/:id', component: require 'app/pages/ProductDetail' }
  { path: '/about', component: require 'app/pages/About' }
  { path: '/contacts', component: require 'app/pages/Contacts' }
]

# Глобальное определение vuejs приложения
app = Vue.createApp
  name: 'app'
  data: ()->
        return  
            dbReady: false
            loading: true
            error: null
            currentLanguage: 'ru'
            availableLanguages: ['ru', 'en', 'tj']
            
            # Глобальное состояние приложения
            appState:
                slides: []
                featuredEvents: []
                blogPosts: []
                products: []
                categories: []
                loading: true
                error: null
            
            # Состояние модальных окон
            modalState:
                isVisible: false
                component: null
                props: {}
  beforeMount: ()->
        debug.log "start beforeMount"
        # определение контекста vuejs приложения как глобальной переменной _
        globalThis._ = @
        
        # Инициализация базы данных
        AppDB.initialize().then =>
            @dbReady = true
            @loadInitialData()
        
        # Слушаем события смены языка
        EventBus.on 'language_changed', (language) =>
            @currentLanguage = language
            @loadInitialData()
        
  mounted: ->
        debug.log "App mounted"
        
  methods:
        # Загрузка начальных данных
        loadInitialData: ->
            @appState.loading = true
            @appState.error = null
            
            Promise.all([
                @loadSlides()
                @loadFeaturedEvents()
                @loadBlogPosts()
                @loadCategories()
            ]).then =>
                @appState.loading = false
            .catch (error) =>
                @appState.error = "Ошибка загрузки данных: "+error
                @appState.loading = false
        
        # Загрузка слайдов
        loadSlides: ->
            AppDB.getSlides(limit: 6).then (slides) =>
                @appState.slides = slides
            .catch (error) =>
                debug.log "Ошибка загрузки слайдов: "+error
        
        # Загрузка избранных мероприятий
        loadFeaturedEvents: ->
            AppDB.getUpcomingEvents(limit: 4).then (events) =>
                @appState.featuredEvents = events
            .catch (error) =>
                debug.log "Ошибка загрузки мероприятий: "+error
        
        # Загрузка блог постов
        loadBlogPosts: ->
            AppDB.getBlogPosts(limit: 6).then (posts) =>
                @appState.blogPosts = posts
            .catch (error) =>
                debug.log "Ошибка загрузки блог постов: "+error
        
        # Загрузка категорий
        loadCategories: ->
            AppDB.getCategories().then (categories) =>
                @appState.categories = categories
            .catch (error) =>
                debug.log "Ошибка загрузки категорий: "+error
        
        # Смена языка
        changeLanguage: (language) ->
            if language in @availableLanguages
                AppDB.multilingual.setLanguage(language)
                @currentLanguage = language
        
        # Поиск по сайту
        search: (query) ->
            if query and query.length > 2
                AppDB.searchContent(query).then (results) ->
                    EventBus.emit('search_results', results)
        
        # Открытие модального окна
        openModal: (component, props = {}) ->
            @modalState.component = component
            @modalState.props = props
            @modalState.isVisible = true
        
        # Закрытие модального окна
        closeModal: ->
            @modalState.isVisible = false
            @modalState.component = null
            @modalState.props = {}
        
  render: (new Function '_ctx', '_cache', renderFns['app/temp.pug'])()
  
  components:
      'themetoggle':    require 'app/shared/ThemeToggle'
      'multilevelmenu': require 'app/shared/MultiLevelMenu'
      'imageslider':    require 'app/shared/ImageSlider'
      'app-link':       require 'app/shared/AppLink'
      'language-switcher': require 'app/shared/LanguageSwitcher'

app.use(VueRouter.createRouter({
  routes: routes
  history: VueRouter.createWebHistory()
  scrollBehavior: (to, from, savedPosition) ->
    if savedPosition
      return savedPosition
    else
      return { x: 0, y: 0 }
}))

# подключаем в body ОБЯЗАТЕЛЬНО!!!
app.mount('body')
