<template>
  <!-- 全局审批通知管理组件 - 无界面，纯逻辑 -->
  <div style="display: none;"></div>
</template>

<script>
import { getPendingApplyList, getPendingTriConfirmList } from '@/api/erf/erf'
import approvalConfig from '@/config/approval-notification.config'

/**
 * 全局审批通知管理器
 *
 * 功能：
 * 1. 登录后自动检查待审批项（经理审批、计划员排产、三方确认）
 * 2. 定时轮询检查新的待审批项（默认5分钟，可在配置文件中修改）
 * 3. 在浏览器右下角弹出合并通知提示
 * 4. 点击不同类型的提醒跳转到对应页面
 *
 * 配置文件：src/config/approval-notification.config.js
 */
export default {
  name: 'ApprovalNotificationManager',

  data() {
    return {
      pollingTimer: null,           // 轮询定时器
      pollingInterval: approvalConfig.polling.interval, // 轮询间隔（从配置文件读取）
      lastCheckTime: null,           // 上次检查时间
      notifiedApplications: new Set(), // 已通知过的申请单号集合（避免重复通知）
      isInitialized: false,          // 是否已初始化
      audioContext: null,            // 音频上下文（用于提示音）
      config: approvalConfig,        // 配置对象
      isChecking: false,             // 是否正在检查中（防止重复调用）
      firstCheckTimeout: null,       // 首次检查的定时器
      activeNotifications: [],       // 当前显示的所有通知实例
      // 上一次各类型待办数量（用于轮询时检测新增）
      lastCounts: {
        manager: 0,
        planner: 0,
        triConfirm: 0
      }
    }
  },

  computed: {
    /**
     * 当前登录用户ID
     */
    currentUserId() {
      return this.$store.state.user.id
    },

    /**
     * 当前登录用户名称
     */
    currentUserName() {
      return this.$store.state.user.name
    },

    /**
     * 当前站点
     */
    currentSite() {
      return this.$store.state.user.site
    },

    /**
     * 工程试验消息通知标志（'Y'=启用通知, 'N'=禁用通知）
     */
    erfMsgFlag() {
      return this.$store.state.user.erfMsgFlag
    },

    /**
     * 是否已登录
     */
    isLoggedIn() {
      return this.currentUserId && this.currentUserId !== 0
    },

    /**
     * 是否需要显示通知（已登录且erfMsgFlag='Y'）
     */
    shouldShowNotification() {
      return this.isLoggedIn && this.erfMsgFlag === 'Y'
    }
  },

  watch: {
    /**
     * 监听用户登录状态变化
     */
    isLoggedIn(newVal, oldVal) {
      console.log(`[审批通知] 登录状态变化: ${oldVal} -> ${newVal}, erfMsgFlag: ${this.erfMsgFlag}, 已初始化: ${this.isInitialized}`)

      // 只有真正的登录状态变化才处理
      if (oldVal === newVal) {
        console.log('[审批通知] 登录状态未变化，跳过')
        return
      }

      if (newVal && !this.isInitialized) {
        // 用户已登录且未初始化，但需要检查 erfMsgFlag
        if (this.erfMsgFlag === 'Y') {
          console.log('[审批通知] 用户已登录且启用通知(watch触发)，初始化通知系统')
          // 延迟执行，避免与 mounted 冲突
          this.$nextTick(() => {
            if (!this.isInitialized && this.shouldShowNotification) {
              this.initializeNotificationSystem()
            }
          })
        } else {
          console.log('[审批通知] 用户已登录但未启用通知功能（erfMsgFlag=N），等待erfMsgFlag变化')
        }
      } else if (!newVal && this.isInitialized) {
        console.log('[审批通知] 用户已登出，停止通知系统')
        this.stopNotificationSystem()
      }
    },

    /**
     * 监听 erfMsgFlag 变化
     */
    erfMsgFlag(newVal, oldVal) {
      console.log(`[审批通知] erfMsgFlag变化: ${oldVal} -> ${newVal}, 登录状态: ${this.isLoggedIn}, 已初始化: ${this.isInitialized}`)

      if (newVal === 'Y' && this.shouldShowNotification && !this.isInitialized) {
        // erfMsgFlag 变为 'Y'，且满足显示通知条件但未初始化，则初始化通知系统
        console.log('[审批通知] erfMsgFlag启用且用户已登录，初始化通知系统')
        this.$nextTick(() => {
          if (!this.isInitialized && this.shouldShowNotification) {
            this.initializeNotificationSystem()
          }
        })
      } else if (newVal === 'Y' && !this.isLoggedIn) {
        // erfMsgFlag 为 'Y' 但用户未登录
        console.log('[审批通知] erfMsgFlag启用但用户未登录，等待登录')
      } else if (newVal === 'N' && this.isInitialized) {
        // erfMsgFlag 变为 'N'，且已初始化，则停止通知系统
        console.log('[审批通知] erfMsgFlag禁用，停止通知系统')
        this.stopNotificationSystem()
      }
    }
  },

  mounted() {
    console.log(`[审批通知] 组件挂载, 登录状态: ${this.isLoggedIn}, erfMsgFlag: ${this.erfMsgFlag}, 已初始化: ${this.isInitialized}`)
    // 组件挂载时，如果需要显示通知且未初始化则初始化
    // 使用延迟确保只执行一次
    this.$nextTick(() => {
      if (this.shouldShowNotification && !this.isInitialized) {
        console.log('[审批通知] 组件挂载时初始化通知系统')
        this.initializeNotificationSystem()
      } else if (!this.shouldShowNotification) {
        console.log(`[审批通知] 用户未启用通知功能（erfMsgFlag=${this.erfMsgFlag}），不初始化`)
      }
    })
  },

  beforeDestroy() {
    // 组件销毁时清理资源
    console.log('[审批通知] 组件销毁，清理所有资源')
    this.stopNotificationSystem()
  },

  methods: {
    /**
     * 初始化通知系统
     */
    initializeNotificationSystem() {
      // 检查是否需要显示通知
      if (!this.shouldShowNotification) {
        console.log(`[审批通知] 用户未启用通知功能（erfMsgFlag=${this.erfMsgFlag}），跳过初始化`)
        return
      }

      // 双重检查锁
      if (this.isInitialized) {
        console.log('[审批通知] 系统已初始化，跳过重复初始化')
        return
      }

      console.log('[审批通知] 开始初始化通知系统...')

      // 立即设置标志，防止并发调用
      this.isInitialized = true

      // 先清理可能存在的旧资源
      this.stopPolling()
      this.closeAllNotifications()

      // 清理可能存在的首次检查定时器
      if (this.firstCheckTimeout) {
        clearTimeout(this.firstCheckTimeout)
        this.firstCheckTimeout = null
      }

      // 延迟后首次检查（避免登录时的接口压力）
      this.firstCheckTimeout = setTimeout(() => {
        if (this.isInitialized && this.isLoggedIn) {
          this.checkPendingApprovals(true)
        }
        this.firstCheckTimeout = null
      }, this.config.polling.firstCheckDelay)

      // 启动定时轮询
      this.startPolling()

      console.log('[审批通知] 通知系统初始化完成')
    },

    /**
     * 停止通知系统
     */
    stopNotificationSystem() {
      console.log('[审批通知] 停止通知系统...')

      // 关闭所有已显示的通知窗口
      this.closeAllNotifications()

      // 停止轮询
      this.stopPolling()

      // 清理首次检查定时器
      if (this.firstCheckTimeout) {
        clearTimeout(this.firstCheckTimeout)
        this.firstCheckTimeout = null
      }

      // 重置状态
      this.isInitialized = false
      this.isChecking = false
      this.notifiedApplications.clear()
      this.lastCheckTime = null
      this.lastCounts = { manager: 0, planner: 0, triConfirm: 0 }

      console.log('[审批通知] 通知系统已停止')
    },

    /**
     * 关闭所有活动的通知窗口
     */
    closeAllNotifications() {
      console.log(`[审批通知] 关闭所有通知窗口，当前数量: ${this.activeNotifications.length}`)

      // 关闭所有通知
      this.activeNotifications.forEach(notification => {
        try {
          if (notification && typeof notification.close === 'function') {
            notification.close()
          }
        } catch (error) {
          console.error('[审批通知] 关闭通知失败:', error)
        }
      })

      // 清空通知列表
      this.activeNotifications = []
    },

    /**
     * 从活动列表中移除指定的通知实例
     * @param {Object} notification - 要移除的通知实例
     */
    removeNotification(notification) {
      const index = this.activeNotifications.indexOf(notification)
      if (index > -1) {
        this.activeNotifications.splice(index, 1)
        console.log(`[审批通知] 已移除通知实例，剩余活动通知数: ${this.activeNotifications.length}`)
      }
    },

    /**
     * 启动定时轮询
     */
    startPolling() {
      if (this.pollingTimer) {
        console.log('[审批通知] 定时器已存在，跳过创建')
        return
      }

      this.pollingTimer = setInterval(() => {
        if (this.isLoggedIn && this.isInitialized) {
          this.checkPendingApprovals(false)
        }
      }, this.pollingInterval)

      console.log(`[审批通知] 定时轮询已启动，定时器ID: ${this.pollingTimer}, 间隔 ${this.pollingInterval / 1000} 秒`)
    },

    /**
     * 停止定时轮询
     */
    stopPolling() {
      if (this.pollingTimer) {
        console.log(`[审批通知] 清除定时器，ID: ${this.pollingTimer}`)
        clearInterval(this.pollingTimer)
        this.pollingTimer = null
      }
    },

    /**
     * 检查所有类型的待办事项（经理审批、计划员排产、三方确认）
     * 三个接口并行调用，结果合并后显示一个通知
     * @param {boolean} isFirstCheck - 是否首次检查
     */
    checkPendingApprovals(isFirstCheck = false) {
      // 检查是否需要显示通知
      if (!this.shouldShowNotification) {
        console.log(`[审批通知] 用户未启用通知功能（erfMsgFlag=${this.erfMsgFlag}），跳过检查`)
        return
      }

      if (!this.isLoggedIn) {
        console.log('[审批通知] 用户未登录，跳过检查')
        return
      }

      // 防止重复调用
      if (this.isChecking) {
        console.log('[审批通知] 正在检查中，跳过本次调用')
        return
      }

      this.isChecking = true
      console.log(`[审批通知] 开始检查所有待办事项... (首次检查: ${isFirstCheck})`)

      // 1. 经理审批查询
      const managerRequest = getPendingApplyList({
        site: this.currentSite,
        currentUserId: this.currentUserId,
        userName: this.currentUserName,
        pageType: 'MANAGER',
        pendingStatus: '已下达',
        page: 1,
        limit: 20
      }).then(({data}) => {
        if (data && data.code === 0) {
          const list = data.rows || (data.page && data.page.list) || []
          return { count: data.totalCount || (data.page && data.page.totalCount) || list.length, list: list }
        }
        return { count: 0, list: [] }
      }).catch(() => ({ count: 0, list: [] }))

      // 2. 计划员排产查询
      const plannerRequest = getPendingApplyList({
        site: this.currentSite,
        currentUserId: this.currentUserId,
        userName: this.currentUserName,
        pageType: 'PLANNER',
        pendingStatus: '已批准',
        page: 1,
        limit: 20
      }).then(({data}) => {
        if (data && data.code === 0) {
          const list = data.rows || (data.page && data.page.list) || []
          return { count: data.totalCount || (data.page && data.page.totalCount) || list.length, list: list }
        }
        return { count: 0, list: [] }
      }).catch(() => ({ count: 0, list: [] }))

      // 3. 三方确认查询
      const triConfirmRequest = getPendingTriConfirmList({
        currentUserId: this.currentUserId,
        site: this.currentSite
      }).then(({data}) => {
        if (data && data.code === 0) {
          const list = data.list || []
          return { count: list.length, list: list }
        }
        return { count: 0, list: [] }
      }).catch(() => ({ count: 0, list: [] }))

      // 并行执行三个查询
      Promise.all([managerRequest, plannerRequest, triConfirmRequest]).then(([managerResult, plannerResult, triConfirmResult]) => {
        const counts = {
          manager: managerResult.count,
          planner: plannerResult.count,
          triConfirm: triConfirmResult.count
        }

        console.log(`[审批通知] 查询结果 - 经理审批: ${counts.manager}, 计划员排产: ${counts.planner}, 三方确认: ${counts.triConfirm}`)

        const totalCount = counts.manager + counts.planner + counts.triConfirm

        if (totalCount > 0) {
          if (isFirstCheck) {
            // 首次检查：显示合并通知
            this.showCombinedNotification(counts)
          } else {
            // 轮询检查：只在有新增时显示通知
            const hasNewItems = counts.manager > this.lastCounts.manager ||
                                counts.planner > this.lastCounts.planner ||
                                counts.triConfirm > this.lastCounts.triConfirm

            if (hasNewItems) {
              // 关闭旧通知，显示新通知
              this.closeAllNotifications()
              this.showCombinedNotification(counts)
            }
          }
        }

        // 更新上次的数量记录
        this.lastCounts = { ...counts }
        this.lastCheckTime = new Date()
        this.isChecking = false
      }).catch(error => {
        console.error('[审批通知] 检查待办事项失败:', error)
        this.isChecking = false
      })
    },

    /**
     * 显示合并通知（包含经理审批、计划员排产、三方确认）
     * 使用 VNode 创建可点击的分区通知
     * @param {Object} counts - 各类型待办数量 { manager, planner, triConfirm }
     */
    showCombinedNotification(counts) {
      const h = this.$createElement
      let notificationRef = null

      // 关闭通知并跳转的辅助函数
      const navigateAndClose = (path) => {
        if (notificationRef) {
          this.removeNotification(notificationRef)
          notificationRef.close()
        }
        this.$router.push({ path: path }).catch(err => {
          this.log('路由跳转失败: ' + err.message, 'warn')
        })
      }

      // 构建通知内容的各个区块
      const sections = []

      // 经理审批区块
      if (counts.manager > 0) {
        sections.push(
          h('div', {
            class: 'notification-item manager-item',
            on: { click: (e) => { e.stopPropagation(); navigateAndClose('erf-expApplyApproval') } }
          }, [
            h('div', { class: 'notification-item-icon' }, [
              h('i', { class: 'el-icon-s-check', style: { color: '#E6A23C', fontSize: '18px' } })
            ]),
            h('div', { class: 'notification-item-content' }, [
              h('p', { class: 'notification-item-text' }, [
                '您有 ',
                h('span', { class: 'count-highlight', style: { color: '#E6A23C' } }, counts.manager),
                ' 个工程试验申请单待审批'
              ]),
              h('p', { class: 'notification-item-link' }, '点击此通知查看详情')
            ])
          ])
        )
      }

      // 计划员排产区块
      if (counts.planner > 0) {
        sections.push(
          h('div', {
            class: 'notification-item planner-item',
            on: { click: (e) => { e.stopPropagation(); navigateAndClose('erf-plannerSchedule') } }
          }, [
            h('div', { class: 'notification-item-icon' }, [
              h('i', { class: 'el-icon-date', style: { color: '#409EFF', fontSize: '18px' } })
            ]),
            h('div', { class: 'notification-item-content' }, [
              h('p', { class: 'notification-item-text' }, [
                '您有 ',
                h('span', { class: 'count-highlight', style: { color: '#409EFF' } }, counts.planner),
                ' 个工程试验申请单待排产'
              ]),
              h('p', { class: 'notification-item-link' }, '点击此通知查看详情')
            ])
          ])
        )
      }

      // 三方确认区块
      if (counts.triConfirm > 0) {
        sections.push(
          h('div', {
            class: 'notification-item tri-confirm-item',
            on: { click: (e) => { e.stopPropagation(); navigateAndClose('erf-triConfirm') } }
          }, [
            h('div', { class: 'notification-item-icon' }, [
              h('i', { class: 'el-icon-finished', style: { color: '#67C23A', fontSize: '18px' } })
            ]),
            h('div', { class: 'notification-item-content' }, [
              h('p', { class: 'notification-item-text' }, [
                '您有 ',
                h('span', { class: 'count-highlight', style: { color: '#67C23A' } }, counts.triConfirm),
                ' 个三方确认工序待确认'
              ]),
              h('p', { class: 'notification-item-link' }, '点击此通知查看详情')
            ])
          ])
        )
      }

      // 如果没有任何待办，不显示通知
      if (sections.length === 0) {
        return
      }

      // 创建完整的通知消息 VNode
      const message = h('div', { class: 'combined-notification-body' }, sections)

      // 创建通知实例
      notificationRef = this.$notify({
        title: '待审批提醒',
        customClass: 'approval-notification combined-notification',
        message: message,
        type: 'warning',
        position: this.config.notification.position,
        duration: this.config.notification.summaryDuration,
        showClose: this.config.notification.showClose,
        onClose: () => {
          this.removeNotification(notificationRef)
        }
      })

      // 保存通知实例
      this.activeNotifications.push(notificationRef)
      console.log(`[审批通知] 已创建合并通知（经理:${counts.manager}, 排产:${counts.planner}, 三方:${counts.triConfirm}），当前活动通知数: ${this.activeNotifications.length}`)
    },

    /**
     * 播放通知提示音
     */
    playNotificationSound() {
      // 检查是否启用提示音
      if (!this.config.sound.enabled || !this.config.features.playSound) {
        return
      }

      try {
        // 使用 Web Audio API 生成简单的提示音
        const audioContext = new (window.AudioContext || window.webkitAudioContext)()
        const oscillator = audioContext.createOscillator()
        const gainNode = audioContext.createGain()

        oscillator.connect(gainNode)
        gainNode.connect(audioContext.destination)

        oscillator.frequency.value = this.config.sound.frequency // 频率
        oscillator.type = 'sine' // 正弦波

        const duration = this.config.sound.duration
        const volume = this.config.sound.volume

        gainNode.gain.setValueAtTime(volume, audioContext.currentTime)
        gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration)

        oscillator.start(audioContext.currentTime)
        oscillator.stop(audioContext.currentTime + duration)
      } catch (error) {
        this.log('播放提示音失败: ' + error.message, 'warn')
      }
    },

    /**
     * 手动触发检查（供外部调用）
     */
    manualCheck() {
      console.log('[审批通知] 手动触发检查')
      this.checkPendingApprovals(false)
    },

    /**
     * 清除指定申请单的通知记录（审批完成后调用）
     * @param {string} applyNo - 申请单号
     */
    clearNotification(applyNo) {
      this.notifiedApplications.delete(applyNo)
      this.log(`已清除申请单 ${applyNo} 的通知记录`, 'info')
    },

    /**
     * 日志输出辅助方法
     * @param {string} message - 日志消息
     * @param {string} level - 日志级别 ('info', 'warn', 'error', 'debug')
     */
    log(message, level = 'info') {
      if (!this.config.logging.enabled) {
        return
      }

      const prefix = this.config.logging.prefix
      const fullMessage = `${prefix} ${message}`

      switch (level) {
        case 'error':
          console.error(fullMessage)
          break
        case 'warn':
          console.warn(fullMessage)
          break
        case 'debug':
          if (this.config.debug.enabled) {
            console.debug(fullMessage)
          }
          break
        case 'info':
        default:
          console.log(fullMessage)
          break
      }
    }
  }
}
</script>

<style scoped>
/* 无需样式 */
</style>
