/**
 * 主题切换工具函数
 * 支持明暗主题切换和主题持久化
 * @author 前端架构师
 */

const THEME_KEY = 'xt-theme'
const THEME_DARK = 'dark'
const THEME_LIGHT = 'light'
const THEME_AUTO = 'auto'

/**
 * 主题管理类
 */
class ThemeManager {
  constructor() {
    this.currentTheme = this.getStoredTheme() || THEME_AUTO
    this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
    this.listeners = new Set()
    
    // 监听系统主题变化
    this.mediaQuery.addEventListener('change', this.handleSystemThemeChange.bind(this))
    
    // 初始化主题
    this.applyTheme(this.currentTheme)
  }

  /**
   * 获取存储的主题
   * @returns {string|null}
   */
  getStoredTheme() {
    try {
      return localStorage.getItem(THEME_KEY)
    } catch (error) {
      console.warn('无法访问 localStorage:', error)
      return null
    }
  }

  /**
   * 存储主题设置
   * @param {string} theme 主题名称
   */
  setStoredTheme(theme) {
    try {
      localStorage.setItem(THEME_KEY, theme)
    } catch (error) {
      console.warn('无法保存主题设置:', error)
    }
  }

  /**
   * 获取系统主题偏好
   * @returns {string}
   */
  getSystemTheme() {
    return this.mediaQuery.matches ? THEME_DARK : THEME_LIGHT
  }

  /**
   * 获取实际应用的主题
   * @param {string} theme 设置的主题
   * @returns {string}
   */
  getEffectiveTheme(theme) {
    if (theme === THEME_AUTO) {
      return this.getSystemTheme()
    }
    return theme
  }

  /**
   * 应用主题到 DOM
   * @param {string} theme 主题名称
   */
  applyTheme(theme) {
    const effectiveTheme = this.getEffectiveTheme(theme)
    const htmlElement = document.documentElement
    
    // 移除所有主题类
    htmlElement.classList.remove(THEME_DARK, THEME_LIGHT)
    
    // 应用新主题
    if (effectiveTheme === THEME_DARK) {
      htmlElement.classList.add(THEME_DARK)
    }
    
    // 设置主题属性
    htmlElement.setAttribute('data-theme', effectiveTheme)
    
    // 触发主题变化事件
    this.notifyListeners(theme, effectiveTheme)
  }

  /**
   * 设置主题
   * @param {string} theme 主题名称
   */
  setTheme(theme) {
    if (![THEME_LIGHT, THEME_DARK, THEME_AUTO].includes(theme)) {
      console.warn('无效的主题名称:', theme)
      return
    }

    this.currentTheme = theme
    this.setStoredTheme(theme)
    this.applyTheme(theme)
  }

  /**
   * 获取当前主题设置
   * @returns {string}
   */
  getTheme() {
    return this.currentTheme
  }

  /**
   * 获取当前生效的主题
   * @returns {string}
   */
  getEffectiveCurrentTheme() {
    return this.getEffectiveTheme(this.currentTheme)
  }

  /**
   * 切换主题（在明暗主题间切换）
   */
  toggleTheme() {
    const currentEffective = this.getEffectiveCurrentTheme()
    const newTheme = currentEffective === THEME_DARK ? THEME_LIGHT : THEME_DARK
    this.setTheme(newTheme)
  }

  /**
   * 是否为暗色主题
   * @returns {boolean}
   */
  isDark() {
    return this.getEffectiveCurrentTheme() === THEME_DARK
  }

  /**
   * 是否为亮色主题
   * @returns {boolean}
   */
  isLight() {
    return this.getEffectiveCurrentTheme() === THEME_LIGHT
  }

  /**
   * 是否为自动主题
   * @returns {boolean}
   */
  isAuto() {
    return this.currentTheme === THEME_AUTO
  }

  /**
   * 处理系统主题变化
   */
  handleSystemThemeChange() {
    if (this.currentTheme === THEME_AUTO) {
      this.applyTheme(THEME_AUTO)
    }
  }

  /**
   * 添加主题变化监听器
   * @param {Function} listener 监听器函数
   */
  addListener(listener) {
    this.listeners.add(listener)
    
    // 返回取消监听的函数
    return () => {
      this.listeners.delete(listener)
    }
  }

  /**
   * 移除主题变化监听器
   * @param {Function} listener 监听器函数
   */
  removeListener(listener) {
    this.listeners.delete(listener)
  }

  /**
   * 通知所有监听器
   * @param {string} theme 设置的主题
   * @param {string} effectiveTheme 实际生效的主题
   */
  notifyListeners(theme, effectiveTheme) {
    const event = {
      theme,
      effectiveTheme,
      isDark: effectiveTheme === THEME_DARK,
      isLight: effectiveTheme === THEME_LIGHT,
      isAuto: theme === THEME_AUTO
    }

    this.listeners.forEach(listener => {
      try {
        listener(event)
      } catch (error) {
        console.error('主题监听器执行出错:', error)
      }
    })
  }

  /**
   * 销毁主题管理器
   */
  destroy() {
    this.mediaQuery.removeEventListener('change', this.handleSystemThemeChange.bind(this))
    this.listeners.clear()
  }

  /**
   * 获取主题色彩值
   * @param {string} colorName 色彩名称
   * @returns {string}
   */
  getThemeColor(colorName) {
    const style = getComputedStyle(document.documentElement)
    return style.getPropertyValue(`--color-${colorName}`).trim()
  }

  /**
   * 设置主题色彩值
   * @param {string} colorName 色彩名称
   * @param {string} colorValue 色彩值
   */
  setThemeColor(colorName, colorValue) {
    document.documentElement.style.setProperty(`--color-${colorName}`, colorValue)
  }

  /**
   * 重置主题色彩值
   * @param {string} colorName 色彩名称
   */
  resetThemeColor(colorName) {
    document.documentElement.style.removeProperty(`--color-${colorName}`)
  }

  /**
   * 获取所有可用主题
   * @returns {Array}
   */
  getAvailableThemes() {
    return [
      { value: THEME_LIGHT, label: '亮色主题', icon: 'el-icon-sunny' },
      { value: THEME_DARK, label: '暗色主题', icon: 'el-icon-moon' },
      { value: THEME_AUTO, label: '跟随系统', icon: 'el-icon-monitor' }
    ]
  }
}

// 创建全局主题管理器实例
const themeManager = new ThemeManager()

/**
 * Vue 插件
 */
const ThemePlugin = {
  install(Vue) {
    // 添加全局属性
    Vue.prototype.$theme = themeManager
    
    // 添加全局方法
    Vue.prototype.$toggleTheme = () => themeManager.toggleTheme()
    Vue.prototype.$setTheme = (theme) => themeManager.setTheme(theme)
    Vue.prototype.$getTheme = () => themeManager.getTheme()
    Vue.prototype.$isDark = () => themeManager.isDark()
    Vue.prototype.$isLight = () => themeManager.isLight()
  }
}

/**
 * 主题切换 Mixin
 */
const ThemeMixin = {
  data() {
    return {
      currentTheme: themeManager.getTheme(),
      isDarkTheme: themeManager.isDark()
    }
  },
  
  created() {
    // 添加主题变化监听
    this.themeUnsubscribe = themeManager.addListener(this.handleThemeChange)
  },
  
  beforeDestroy() {
    // 移除监听器
    if (this.themeUnsubscribe) {
      this.themeUnsubscribe()
    }
  },
  
  methods: {
    handleThemeChange(event) {
      this.currentTheme = event.theme
      this.isDarkTheme = event.isDark
      
      // 如果组件有自定义的主题变化处理方法，则调用
      if (typeof this.onThemeChange === 'function') {
        this.onThemeChange(event)
      }
    }
  }
}

/**
 * 获取主题相关的工具函数
 */
export const themeUtils = {
  /**
   * 根据主题获取对比色
   * @param {string} theme 主题
   * @returns {string}
   */
  getContrastColor(theme = themeManager.getEffectiveCurrentTheme()) {
    return theme === THEME_DARK ? '#ffffff' : '#000000'
  },

  /**
   * 根据主题获取背景色
   * @param {string} theme 主题
   * @returns {string}
   */
  getBackgroundColor(theme = themeManager.getEffectiveCurrentTheme()) {
    return theme === THEME_DARK ? '#111827' : '#ffffff'
  },

  /**
   * 检查是否支持暗色主题
   * @returns {boolean}
   */
  supportsDarkMode() {
    return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all'
  },

  /**
   * 获取主题图标
   * @param {string} theme 主题
   * @returns {string}
   */
  getThemeIcon(theme) {
    const icons = {
      [THEME_LIGHT]: 'el-icon-sunny',
      [THEME_DARK]: 'el-icon-moon',
      [THEME_AUTO]: 'el-icon-monitor'
    }
    return icons[theme] || 'el-icon-monitor'
  },

  /**
   * 获取主题描述
   * @param {string} theme 主题
   * @returns {string}
   */
  getThemeDescription(theme) {
    const descriptions = {
      [THEME_LIGHT]: '亮色主题，适合白天使用',
      [THEME_DARK]: '暗色主题，适合夜间使用',
      [THEME_AUTO]: '自动跟随系统设置'
    }
    return descriptions[theme] || '未知主题'
  }
}

// 导出常量
export {
  THEME_KEY,
  THEME_DARK,
  THEME_LIGHT,
  THEME_AUTO,
  ThemeManager,
  ThemePlugin,
  ThemeMixin
}

// 默认导出主题管理器实例
export default themeManager
