/**
 * 快捷键 Mixin
 *
 * 功能：为 Vue 组件提供快捷键注册能力，基于作用域隔离
 *
 * 【核心概念】
 *
 * 作用域（Scope）：
 * - 路由作用域：/path::CoverPath
 * - 嵌套作用域：/path::Cover1/Cover2/Cover3
 *
 * 作用域基于栅格自身的 getGridScopePath() 生成，
 * 不再依赖 XTab 的激活状态。
 *
 * 【使用方式】
 *
 * export default {
 *   mixins: [shortcutMixin],
 *   created() { this.registerShortcutsIfNeeded() },
 *   beforeDestroy() { this.unregisterShortcuts() }
 * }
 */

import { shortcutManager } from '@vue2-client/base-client/utils/shortcutManager'
// import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'

const log = (env => {
  if (env !== 'development') return () => {}
  return (tag, ...args) => console.log(`[ShortcutMixin] [${tag}]`, ...args)
})(process.env.NODE_ENV)

export const shortcutMixin = {
  inject: {
    getGridScopePath: {
      from: 'getGridScopePath',
      default: null
    }
  },

  data() {
    return {
      shortcutScopeId: null,
      shortcutInstanceId: null,
      shortcutsRegistered: false,
      isShortcutActive: false
    }
  },

  created() {
    if (!shortcutManager.isEnabled) return
    if (!this.shortcutInstanceId) {
      this.shortcutInstanceId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`
    }
  },

  beforeDestroy() {
    this.unregisterShortcuts()
  },

  methods: {
    // ========== 注册入口 ==========

    registerShortcutsIfNeeded() {
      if (!shortcutManager.isEnabled) return

      const config = this.getShortcutConfig()
      if (!config || this.shortcutsRegistered) return

      this.$nextTick(() => {
        this._doRegisterShortcuts(config)
      })
    },

    async _doRegisterShortcuts(config) {
      await this.registerShortcuts(config)
      this.shortcutsRegistered = true
    },

    onShortcutMixinReady() {
      this.registerShortcutsIfNeeded()
    },

    getShortcutConfig() {
      if (this.columns) {
        return {
          columns: this.columns,
          configName: this.config?.configName,
          scopeType: this.shortcutScopeType || 'page'
        }
      }
      return null
    },

    // ========== 快捷键注册 ==========

    async registerShortcuts(config) {
      const { columns } = config
      if (!columns) return

      const routePath = this.getRoutePath()

      let gridScopePath = null
      if (typeof this.getGridScopePath === 'function') {
        gridScopePath = this.getGridScopePath()
      }

      if (gridScopePath) {
        this.shortcutScopeId = `${routePath}::${gridScopePath}`
      } else {
        this.shortcutScopeId = shortcutManager.generateRouteScope(routePath)
      }

      log('info', `注册开始 scope=${this.shortcutScopeId} 组件=${this.$options.name} 实例=${this.shortcutInstanceId}`)

      this.activateShortcuts()

      const nestedConfigs = []
      this.scanColumnsRecursively(columns, nestedConfigs)

      if (nestedConfigs.length > 0) {
        await Promise.all(nestedConfigs.map(cfg => this.loadAndScanNestedConfig(cfg)))
      }

      log('info', `✅ 注册完成 scope=${this.shortcutScopeId} 组件=${this.$options.name} 实例=${this.shortcutInstanceId}`)
    },

    // ========== 扫描方法 ==========

    scanColumnsRecursively(columns, nestedConfigs = [], parentTabPath = null) {
      const normalizedCols = columns.length === 1 && Array.isArray(columns[0]) && !columns[0].slotRef
        ? columns[0]
        : columns

      // 获取当前组件自己的路径，用于传递给子容器
      let myPath = ''
      if (typeof this.getGridScopePath === 'function') {
        myPath = this.getGridScopePath()
      }
      const finalParentPath = parentTabPath || myPath || ''

      normalizedCols.forEach((col) => {
        if (Array.isArray(col)) {
          col.forEach((cell) => {
            this.scanAndRegisterFromCellWithScope(cell, this.shortcutScopeId)
            this.collectNestedConfig(cell, nestedConfigs, finalParentPath)
          })
        } else {
          this.scanAndRegisterFromCellWithScope(col, this.shortcutScopeId)
          this.collectNestedConfig(col, nestedConfigs, finalParentPath)
        }
      })
    },

    scanColumnsRecursivelyWithScope(columns, scopeId, parentTabPath = null) {
      const normalizedCols = columns.length === 1 && Array.isArray(columns[0]) && !columns[0].slotRef
        ? columns[0]
        : columns

      const nestedConfigs = []

      // 获取当前组件自己的路径
      let myPath = ''
      if (typeof this.getGridScopePath === 'function') {
        myPath = this.getGridScopePath()
      }
      const finalParentPath = parentTabPath || myPath || ''

      normalizedCols.forEach((col) => {
        if (Array.isArray(col)) {
          col.forEach((cell) => {
            this.scanAndRegisterFromCellWithScope(cell, scopeId)
            this.collectNestedConfig(cell, nestedConfigs, finalParentPath)
          })
        } else {
          this.scanAndRegisterFromCellWithScope(col, scopeId)
          this.collectNestedConfig(col, nestedConfigs, finalParentPath)
        }
      })

      if (nestedConfigs.length > 0) {
        return Promise.all(nestedConfigs.map(cfg => this.loadAndScanNestedConfig(cfg)))
      }
      return Promise.resolve()
    },

    // ========== 收集嵌套配置 ==========

    collectNestedConfig(cell, configs, parentTabPath = null) {
      const slotType = cell.slotType?.toLowerCase() || ''

      const containerTypes = [
        'cover', 'tab', 'htab', 'x-tab', 'h-tab',
        'x-report-grid', 'x-sidebar', 'report-grid'
      ]

      if (containerTypes.includes(slotType) && cell.slotConfig) {
        let myPath = ''
        if (typeof this.getGridScopePath === 'function') {
          myPath = this.getGridScopePath()
        }
        // 只传父级路径，不拼接 cell.slotConfig
        // 每个组件自己在 provide.getGridScopePath 中拼接自己的配置名
        const finalParentPath = parentTabPath || myPath || ''

        configs.push({
          type: slotType,
          slotConfig: cell.slotConfig,
          serviceName: cell.serviceName,
          parentTabPath: finalParentPath
        })
      }

      if (cell.data && Array.isArray(cell.data)) {
        this.collectSlotConfigsFromArray(cell.data, configs, cell.serviceName, null, parentTabPath)
      }
    },

    collectSlotConfigsFromArray(dataArray, configs, serviceName, tabKey = null, parentTabPath = null) {
      dataArray.forEach(item => {
        if (item.slotConfig) {
          const fullTabKey = this.buildFullTabKey(parentTabPath, tabKey)
          configs.push({
            type: 'slot',
            slotConfig: item.slotConfig,
            serviceName: item.serviceName || serviceName,
            parentTabPath: fullTabKey
          })
        }
        if (item.data && Array.isArray(item.data)) {
          const newTabKey = item.slotConfig || item.title || item.key || tabKey
          const newParentTabPath = this.buildFullTabKey(parentTabPath, tabKey)
          this.collectSlotConfigsFromArray(item.data, configs, item.serviceName || serviceName, newTabKey, newParentTabPath)
        }
      })
    },

    buildFullTabKey(parentTabKey, tabKey) {
      if (!tabKey) return parentTabKey
      if (!parentTabKey) return tabKey
      return `${parentTabKey}/${tabKey}`
    },

    isTabContainer(config) {
      return config?.data && Array.isArray(config.data) && config.data.length > 0
    },

    // ========== 加载嵌套配置 ==========

    loadAndScanNestedConfig(config, visited = new Set()) {
      const configKey = `${config.serviceName || ''}:${config.slotConfig}`

      if (visited.has(configKey)) {
        log('warn', `循环引用跳过: ${configKey}`)
        return Promise.resolve()
      }
      visited.add(configKey)

      return new Promise((resolve) => {
        this.getConfigByName(config.slotConfig, config.serviceName, async (res) => {
          if (this.isTabContainer(res)) {
            const tabItems = res.data || []

            const validPromises = tabItems
              .filter(item => item?.slotConfig)
              .map(item => {
                const tabKey = item.slotConfig || item.title || item.key
                const fullTabKey = this.buildFullTabKey(config.parentTabPath, tabKey)

                return this.loadAndScanNestedConfig({
                  type: item.slotType || 'cover',
                  slotConfig: item.slotConfig,
                  serviceName: item.serviceName || config.serviceName,
                  parentTabPath: fullTabKey
                }, new Set(visited))
              })

            if (validPromises.length > 0) {
              await Promise.all(validPromises)
            }
            resolve()
            return
          }

          // 如果是栅格/cover 类型，不代为注册
          // 让内层 Cover 自己挂载后通过 registerShortcutsIfNeeded 注册
          if (res?.columns) {
            log('info', `嵌套 Cover 配置已加载，等待内层组件自行注册: ${configKey}`)
          }

          resolve()
        }, this.env === 'dev')
      })
    },

    // ========== 快捷键激活/停用 ==========

    activateShortcuts() {
      if (this.shortcutScopeId) {
        shortcutManager.setScopeActive(this.shortcutScopeId, true)
        this.isShortcutActive = true
      }
    },

    deactivateShortcuts() {
      if (this.shortcutScopeId) {
        shortcutManager.setScopeActive(this.shortcutScopeId, false)
        this.isShortcutActive = false
      }
    },

    // ========== 快捷键扫描与注册 ==========

    scanAndRegisterFromCellWithScope(cell, scopeId) {
      if (!cell) return

      const hasShortcuts = cell.events && Array.isArray(cell.events) &&
        cell.events.some(e => e.shortcut || (e.shortcuts && e.shortcuts.length > 0))

      console.log('[scanAndRegister] hasShortcuts:', hasShortcuts, 'cell.slotRef:', cell.slotRef)

      if (!hasShortcuts) return

      cell.events.forEach((event, eventIndex) => {
        console.log('[scanAndRegister] event.shortcuts:', event.shortcuts, 'event.shortcut:', event.shortcut)

        if (event.shortcuts && Array.isArray(event.shortcuts)) {
          event.shortcuts.forEach((shortcutKey) => {
            console.log('[scanAndRegister] 注册 shortcuts 中的:', shortcutKey)
            this.registerShortcutWithScope(cell, event, eventIndex, scopeId, shortcutKey)
          })
        }
        if (event.shortcut) {
          console.log('[scanAndRegister] 注册 shortcut:', event.shortcut)
          this.registerShortcutWithScope(cell, event, eventIndex, scopeId, event.shortcut)
        }
      })
    },

    registerShortcutWithScope(cellConfig, eventConfig, eventIndex, scopeId, shortcutKey) {
      // shortcutKey 是传入的具体快捷键，优先使用；否则从 eventConfig.shortcut 取
      const key = shortcutKey || eventConfig.shortcut
      if (!key) return

      const context = this.createShortcutContext(cellConfig, eventConfig, eventIndex, key)

      shortcutManager.register({
        key: key,
        action: eventConfig,
        scope: scopeId,
        context: context,
        cellRef: cellConfig.slotRef,
        isActive: true,
        instanceId: this.shortcutInstanceId
      })

      log('reg', `✅ 注册 ${key} → scope=${scopeId} cellRef=${cellConfig.slotRef || '-'}`)
    },

    // createShortcutContext(cellConfig, eventConfig, eventIndex, shortcutKey) {
    //   return {
    //     ...this,
    //     getComponent: (ref) => this.shortcutGetComponent(ref),
    //     findComponent: (ref) => this.shortcutFindComponent(ref),
    //     cellConfig,
    //     eventConfig,
    //     eventIndex,
    //     slotRef: cellConfig.slotRef,
    //     shortcutKey,  // ✅ 新增：触发的快捷键
    //     triggerEvent: (type, ...args) => {
    //       const event = cellConfig.events?.find(e => e.type === type)
    //       if (event?.customFunction) {
    //         executeStrFunctionByContext(this, event.customFunction, args)
    //       }
    //     }
    //   }
    // },
    createShortcutContext(cellConfig, eventConfig, eventIndex, shortcutKey) {
      return this
    },

    // ========== 组件查找 ==========

    shortcutGetComponent(ref) {
      if (this.getComponentByName) {
        return this.getComponentByName(ref)
      }
      const refName = `dynamicComponent_${ref}`
      const component = this.$refs[refName]?.[0]
      return component || null
    },

    shortcutFindComponent(ref) {
      if (this.findComponentByName) {
        return this.findComponentByName(this, ref, 10, 'parent')
      }
      return this.shortcutGetComponent(ref)
    },

    // ========== 路由路径 ==========

    getRoutePath() {
      if (this.$route) return this.$route.path
      return 'default'
    },

    // ========== 清理 ==========

    unregisterShortcuts() {
      if (this.shortcutInstanceId) {
        shortcutManager.clearInstance(this.shortcutInstanceId)
      }

      if (this.shortcutScopeId) {
        this.deactivateShortcuts()
        log('info', `🗑️ 注销 scope=${this.shortcutScopeId} 实例=${this.shortcutInstanceId}`)
        this.shortcutScopeId = null
        this.shortcutsRegistered = false
      }
    },

    async rescanShortcuts() {
      if (this._rescanInProgress) return
      this._rescanInProgress = true

      try {
        if (this.shortcutInstanceId) {
          shortcutManager.clearInstance(this.shortcutInstanceId)
        }

        if (this.shortcutScopeId) {
          this.shortcutScopeId = null
        }
        this.shortcutsRegistered = false

        const config = this.getShortcutConfig()
        if (config && config.columns && config.columns.length > 0) {
          await this.registerShortcuts(config)
          this.shortcutsRegistered = true
        }
      } finally {
        this._rescanInProgress = false
      }
    }
  }
}

export default shortcutMixin
