/**
 * 应用入口文件
 * 初始化应用、注册插件、配置全局设置
 */

import { createSSRApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'

// 导入配置
import { CONFIG, FEATURE_FLAGS } from '@/common/config/app.config.js'

// 导入插件
import pluginManager, {
  RequestInterceptorPlugin,
  RouteInterceptorPlugin,
  ErrorHandlerPlugin,
  PerformancePlugin,
  CachePlugin
} from '@/common/plugins/index.js'

// 导入工具类
import { createLogger } from '@/common/utils/logger.js'
import { permission } from '@/common/utils/permission.js'
import { storage } from '@/common/utils/storage.js'

// 导入API
import api from '@/common/api/index.js'

// 导入样式
import '@/common/styles/index.scss'

const logger = createLogger('Main')

export function createApp() {
  const app = createSSRApp(App)
  
  // 创建 Pinia 状态管理
  const pinia = createPinia()
  app.use(pinia)
  
  // 初始化权限管理
  permission.init?.()
  
  // 注册插件
  registerPlugins(app)
  
  // 配置全局属性
  setupGlobalProperties(app)
  
  // 配置全局错误处理
  setupErrorHandling(app)
  
  // 初始化应用
  initializeApp()
  
  logger.info('Application created successfully', {
    version: CONFIG.APP_VERSION,
    environment: CONFIG.NODE_ENV
  })
  
  return {
    app,
    Pinia: pinia
  }
}

/**
 * 注册插件
 */
function registerPlugins(app) {
  // 请求拦截器插件
  pluginManager.register(new RequestInterceptorPlugin({
    request: (config) => {
      // 添加认证头
      const token = storage.get('token')
      if (token) {
        config.header = config.header || {}
        config.header.Authorization = `Bearer ${token}`
      }
      
      // 添加公共参数
      config.header = {
        ...config.header,
        'Content-Type': 'application/json',
        'X-App-Version': CONFIG.APP_VERSION || '1.0.0',
        'X-Platform': 'miniprogram'
      }
      
      logger.api(config.method || 'GET', config.url, config.data, 0, 0)
      return config
    },
    response: (response) => {
      // 统一处理响应
      if (response.statusCode === 401) {
        // 清除登录信息
        storage.remove('token')
        storage.remove('userInfo')
        
        // 跳转到登录页
        uni.reLaunch({
          url: '/pages/login/login'
        })
        
        return Promise.reject(new Error('登录已过期'))
      }
      
      if (response.statusCode >= 400) {
        const error = new Error(response.data?.message || '请求失败')
        error.code = response.statusCode
        error.data = response.data
        return Promise.reject(error)
      }
      
      return response
    },
    error: (error) => {
      logger.error('Request error', null, error)
      
      uni.showToast({
        title: error.message || '网络错误',
        icon: 'none',
        duration: 2000
      })
    }
  }))
  
  // 路由拦截器插件
  pluginManager.register(new RouteInterceptorPlugin({
    beforeEach: (to, method) => {
      logger.debug('Route before', { to, method })
      
      // 检查页面权限
      if (to.url && to.url.includes('/pages/admin/')) {
        if (!permission.checkRole(['admin', 'super_admin'], 'or')) {
          uni.showToast({
            title: '权限不足',
            icon: 'none'
          })
          return false
        }
      }
      
      return to
    },
    afterEach: (result, method) => {
      logger.debug('Route after', { result, method })
    }
  }))
  
  // 错误处理插件
  pluginManager.register(new ErrorHandlerPlugin({
    onError: (error, instance, info) => {
      logger.error('Application error', { info }, error)
      
      // 在开发环境显示错误详情
      if (CONFIG.DEBUG) {
        console.error('Vue Error:', error)
        console.error('Component:', instance)
        console.error('Info:', info)
      }
      
      // 显示用户友好的错误信息
      uni.showToast({
        title: '应用出现错误',
        icon: 'none',
        duration: 2000
      })
    },
    onUnhandledRejection: (event) => {
      logger.error('Unhandled promise rejection', { reason: event.reason })
      
      if (CONFIG.DEBUG) {
        console.error('Unhandled Promise Rejection:', event.reason)
      }
    }
  }))
  
  // 性能监控插件
  if (FEATURE_FLAGS.PERFORMANCE_MONITORING) {
    pluginManager.register(new PerformancePlugin({
      enabled: true,
      sampleRate: CONFIG.NODE_ENV === 'production' ? 0.1 : 1.0
    }))
  }
  
  // 缓存插件
  pluginManager.register(new CachePlugin({
    defaultExpire: 30 * 60 * 1000, // 30分钟
    maxSize: 10 * 1024 * 1024, // 10MB
    cleanupInterval: 10 * 60 * 1000 // 10分钟
  }))
  
  // 安装所有插件
  pluginManager.installAll(app)
}

/**
 * 配置全局属性
 */
function setupGlobalProperties(app) {
  // 全局配置
  app.config.globalProperties.$config = CONFIG
  app.config.globalProperties.$features = FEATURE_FLAGS
  
  // 工具类
  app.config.globalProperties.$logger = logger
  app.config.globalProperties.$permission = permission
  app.config.globalProperties.$storage = storage
  app.config.globalProperties.$api = api
  
  // 常用方法
  app.config.globalProperties.$toast = (title, icon = 'none', duration = 2000) => {
    uni.showToast({ title, icon, duration })
  }
  
  app.config.globalProperties.$loading = {
    show: (title = '加载中...') => uni.showLoading({ title }),
    hide: () => uni.hideLoading()
  }
  
  app.config.globalProperties.$modal = (options) => {
    return new Promise((resolve) => {
      uni.showModal({
        title: options.title || '提示',
        content: options.content || '',
        confirmText: options.confirmText || '确定',
        cancelText: options.cancelText || '取消',
        success: (res) => resolve(res.confirm),
        fail: () => resolve(false)
      })
    })
  }
  
  // 格式化工具
  app.config.globalProperties.$filters = {
    currency: (value) => {
      if (!value) return '0.00'
      return parseFloat(value).toLocaleString('zh-CN', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      })
    },
    
    date: (value, format = 'YYYY-MM-DD') => {
      if (!value) return ''
      const date = new Date(value)
      
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hour = String(date.getHours()).padStart(2, '0')
      const minute = String(date.getMinutes()).padStart(2, '0')
      const second = String(date.getSeconds()).padStart(2, '0')
      
      return format
        .replace('YYYY', year)
        .replace('MM', month)
        .replace('DD', day)
        .replace('HH', hour)
        .replace('mm', minute)
        .replace('ss', second)
    },
    
    fileSize: (bytes) => {
      if (!bytes) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
    },
    
    truncate: (text, length = 50) => {
      if (!text) return ''
      return text.length > length ? text.substring(0, length) + '...' : text
    }
  }
}

/**
 * 配置全局错误处理
 */
function setupErrorHandling(app) {
  // Vue 错误处理
  app.config.errorHandler = (error, instance, info) => {
    logger.error('Vue error handler', { info }, error)
  }
  
  // 全局未捕获错误
  if (typeof uni !== 'undefined') {
    uni.onError((error) => {
      logger.error('Global error handler', null, new Error(error))
    })
    
    uni.onUnhandledRejection((event) => {
      logger.error('Global unhandled rejection', { reason: event.reason })
    })
  }
  
  // 网络错误处理
  uni.onNetworkStatusChange((res) => {
    if (!res.isConnected) {
      uni.showToast({
        title: '网络连接已断开',
        icon: 'none',
        duration: 3000
      })
    }
  })
}

/**
 * 初始化应用
 */
function initializeApp() {
  // 检查更新
  if (typeof uni !== 'undefined' && uni.getUpdateManager) {
    const updateManager = uni.getUpdateManager()
    
    updateManager.onCheckForUpdate((res) => {
      if (res.hasUpdate) {
        logger.info('New version available')
      }
    })
    
    updateManager.onUpdateReady(() => {
      uni.showModal({
        title: '更新提示',
        content: '新版本已经准备好，是否重启应用？',
        success: (res) => {
          if (res.confirm) {
            updateManager.applyUpdate()
          }
        }
      })
    })
    
    updateManager.onUpdateFailed(() => {
      logger.error('Update failed')
    })
  }
  
  // 初始化用户信息
  const token = storage.get('token')
  if (token) {
    // 验证 token 有效性
    api.user.getCurrentUser().catch(() => {
      // token 无效，清除登录信息
      storage.remove('token')
      storage.remove('userInfo')
    })
  }
  
  // 初始化系统信息
  try {
    const systemInfo = uni.getSystemInfoSync()
    logger.info('System info', {
      platform: systemInfo.platform,
      system: systemInfo.system,
      version: systemInfo.version,
      screenWidth: systemInfo.screenWidth,
      screenHeight: systemInfo.screenHeight
    })
    
    // 设置全局系统信息
    uni.$systemInfo = systemInfo
  } catch (error) {
    logger.error('Failed to get system info', null, error)
  }
  
  // 初始化网络状态
  uni.getNetworkType({
    success: (res) => {
      logger.info('Network type', { networkType: res.networkType })
      uni.$networkType = res.networkType
    }
  })
  
  logger.info('Application initialized successfully')
}