import { onBeforeUnmount, onMounted, onUnmounted, nextTick } from 'vue'
import { driver, type Driver, type DriveStep } from 'driver.js'
import 'driver.js/dist/driver.css'
import { useAuthStore as useUserStore } from '@/stores/auth'
import { useOnboardingStore } from '@/stores/onboarding'
import { useI18n } from 'vue-i18n'
import { getAdminSteps, getUserSteps } from '@/components/Guide/steps'

export interface OnboardingOptions {
  steps: DriveStep[]
  storageKey?: string
  autoStart?: boolean
  onComplete?: () => void
}

export function useOnboardingTour(options: OnboardingOptions) {
  const { t } = useI18n()
  const userStore = useUserStore()
  const onboardingStore = useOnboardingStore()
  const storageVersion = 'v4_interactive' // Bump version for new tour type

  // Timing constants for better maintainability
  const TIMING = {
    INTERACTIVE_WAIT_MS: 800,        // Default wait time for interactive steps
    SELECT_WAIT_MS: 2500,            // Extended wait for Select components
    ELEMENT_TIMEOUT_MS: 8000,        // Timeout for element detection
    AUTO_START_DELAY_MS: 1000        // Delay before auto-starting tour
  } as const

  // 使用 store 管理的全局 driver 实例
  let driverInstance: Driver | null = onboardingStore.getDriverInstance()
  let currentClickListener: {
    element: HTMLElement
    handler: () => void
    keyHandler?: (e: KeyboardEvent) => void
    originalTabIndex?: string | null
    eventTypes?: string[] // Track which event types were added
  } | null = null
  let autoStartTimer: ReturnType<typeof setTimeout> | null = null
  let globalKeyboardHandler: ((e: KeyboardEvent) => void) | null = null

  const getStorageKey = () => {
    const baseKey = options.storageKey ?? 'onboarding_tour'
    const userId = userStore.user?.id ?? 'guest'
    const role = userStore.user?.role ?? 'user'
    return `${baseKey}_${userId}_${role}_${storageVersion}`
  }

  const hasSeen = () => {
    return localStorage.getItem(getStorageKey()) === 'true'
  }

  const markAsSeen = () => {
    localStorage.setItem(getStorageKey(), 'true')
  }

  const clearSeen = () => {
    localStorage.removeItem(getStorageKey())
  }

  /**
   * 检查元素是否存在，如果不存在则重试
   */
  const ensureElement = async (selector: string, timeout = 5000): Promise<boolean> => {
    const startTime = Date.now()
    while (Date.now() - startTime < timeout) {
      const element = document.querySelector(selector)
      if (element && element.getBoundingClientRect().height > 0) {
        return true
      }
      await new Promise((resolve) => setTimeout(resolve, 150))
    }
    return false
  }

  const startTour = async (startIndex = 0) => {
    // 动态获取当前用户角色和步骤
    const isAdmin = userStore.user?.role === 'admin'
    const steps = isAdmin ? getAdminSteps(t) : getUserSteps(t)

    // 确保 DOM 就绪
    await nextTick()

    // 如果指定了起始步骤，确保元素可见
    const currentStep = steps[startIndex]
    if (currentStep?.element && typeof currentStep.element === 'string') {
      await ensureElement(currentStep.element, TIMING.ELEMENT_TIMEOUT_MS)
    }

    if (driverInstance) {
      driverInstance.destroy()
    }

    // 创建新的 driver 实例并存储到 store
    driverInstance = driver({
      showProgress: true,
      steps,
      animate: true,
      allowClose: false, // 禁止点击遮罩关闭
      stagePadding: 4,
      popoverClass: 'theme-tour-popover',
      nextBtnText: t('common.next'),
      prevBtnText: t('common.back'),
      doneBtnText: t('common.confirm'),

      // 导航处理
      onNextClick: async (_el, _step, { config, state }) => {
        // 如果是最后一步，点击则是"完成"
        if (state.activeIndex === (config.steps?.length ?? 0) - 1) {
          markAsSeen()
          driverInstance?.destroy()
          onboardingStore.setDriverInstance(null)
        } else {
          // 注意：交互式步骤通常隐藏 Next 按钮，此处逻辑为防御性编程
          const currentIndex = state.activeIndex ?? 0
          const currentStep = steps[currentIndex]
          const isInteractiveStep = currentStep?.popover?.showButtons?.length === 1 &&
                                     currentStep?.popover.showButtons[0] === 'close'

          if (isInteractiveStep && currentStep.element) {
            const targetElement = typeof currentStep.element === 'string'
              ? document.querySelector(currentStep.element) as HTMLElement
              : currentStep.element as HTMLElement

            if (targetElement) {
              const isClickable = !['INPUT', 'TEXTAREA', 'SELECT'].includes(targetElement.tagName)
              if (isClickable) {
                targetElement.click()
                return
              }
            }
          }
          driverInstance?.moveNext()
        }
      },
      onPrevClick: () => {
        driverInstance?.movePrevious()
      },
      onCloseClick: () => {
        if (confirm(t('onboarding.confirmExit'))) {
          driverInstance?.destroy()
          onboardingStore.setDriverInstance(null)
        }
      },

      // 渲染时重组 Footer 布局
      onPopoverRender: (popover, { config, state }) => {
        // Class name constants for easier maintenance
        const CLASS_REORGANIZED = 'reorganized'
        const CLASS_FOOTER_LEFT = 'footer-left'
        const CLASS_FOOTER_RIGHT = 'footer-right'
        const CLASS_SKIP_BTN = 'header-skip-btn'
        const CLASS_DONE_BTN = 'driver-popover-done-btn'
        const CLASS_TITLE_TEXT = 'driver-popover-title-text'
        const CLASS_PROGRESS_TEXT = 'driver-popover-progress-text'
        const CLASS_NEXT_BTN = 'driver-popover-next-btn'
        const CLASS_PREV_BTN = 'driver-popover-prev-btn'

        try {
          const { title: titleEl, footer: footerEl, nextButton, previousButton } = popover

          // Defensive check: ensure popover elements exist
          if (!titleEl || !footerEl) {
            console.warn('Onboarding: Missing popover elements')
            return
          }

          // 1. 顶部：添加 "不再提示" 按钮
          if (!titleEl.querySelector(`.${CLASS_SKIP_BTN}`)) {
            const titleText = titleEl.innerText
            if (!titleEl.querySelector(`.${CLASS_TITLE_TEXT}`)) {
              const titleSpan = document.createElement('span')
              titleSpan.className = CLASS_TITLE_TEXT
              titleSpan.textContent = titleText
              titleEl.textContent = ''
              titleEl.appendChild(titleSpan)
            }

            const skipBtn = document.createElement('button')
            skipBtn.className = CLASS_SKIP_BTN
            skipBtn.innerText = t('onboarding.dontShowAgain')
            skipBtn.title = t('onboarding.dontShowAgainTitle')
            skipBtn.type = 'button'
            skipBtn.setAttribute('aria-label', t('onboarding.dontShowAgain'))
            skipBtn.onclick = (e) => {
              e.stopPropagation()
              if (confirm(t('onboarding.confirmDontShow'))) {
                markAsSeen()
                driverInstance?.destroy()
                onboardingStore.setDriverInstance(null)
              }
            }
            titleEl.appendChild(skipBtn)
          }

          // 1.5 交互式步骤提示
          const currentStep = steps[state.activeIndex ?? 0]
          const isInteractive = currentStep?.popover?.showButtons?.length === 1 &&
                               currentStep?.popover?.showButtons[0] === 'close'

          if (isInteractive && popover.description) {
            const hintClass = 'driver-popover-description-hint'
            if (!popover.description.querySelector(`.${hintClass}`)) {
              const hint = document.createElement('div')
              hint.className = `${hintClass} mt-2 text-xs text-gray-500 flex items-center gap-1`

              const iconSpan = document.createElement('span')
              iconSpan.className = 'i-mdi-keyboard-return mr-1'

              const textNode = document.createTextNode(
                t('onboarding.interactiveHint', 'Press Enter or Click to continue'),
              )

              hint.appendChild(iconSpan)
              hint.appendChild(textNode)
              popover.description.appendChild(hint)
            }
          }

          // 2. 底部：DOM 重组
          if (!footerEl.classList.contains(CLASS_REORGANIZED)) {
            footerEl.classList.add(CLASS_REORGANIZED)

            const progressEl = footerEl.querySelector(`.${CLASS_PROGRESS_TEXT}`)
            const nextBtnEl = nextButton || footerEl.querySelector(`.${CLASS_NEXT_BTN}`)
            const prevBtnEl = previousButton || footerEl.querySelector(`.${CLASS_PREV_BTN}`)

            const leftContainer = document.createElement('div')
            leftContainer.className = CLASS_FOOTER_LEFT

            const rightContainer = document.createElement('div')
            rightContainer.className = CLASS_FOOTER_RIGHT

            if (progressEl) leftContainer.appendChild(progressEl)

            const shortcutsEl = document.createElement('div')
            shortcutsEl.className = 'footer-shortcuts'

            const shortcut1 = document.createElement('span')
            shortcut1.className = 'shortcut-item'
            const kbd1 = document.createElement('kbd')
            kbd1.textContent = '←'
            const kbd2 = document.createElement('kbd')
            kbd2.textContent = '→'
            shortcut1.appendChild(kbd1)
            shortcut1.appendChild(kbd2)
            shortcut1.appendChild(
              document.createTextNode(` ${t('onboarding.navigation.flipPage')}`),
            )

            const shortcut2 = document.createElement('span')
            shortcut2.className = 'shortcut-item'
            const kbd3 = document.createElement('kbd')
            kbd3.textContent = 'ESC'
            shortcut2.appendChild(kbd3)
            shortcut2.appendChild(
              document.createTextNode(` ${t('onboarding.navigation.exit')}`),
            )

            shortcutsEl.appendChild(shortcut1)
            shortcutsEl.appendChild(shortcut2)
            leftContainer.appendChild(shortcutsEl)

            if (prevBtnEl) rightContainer.appendChild(prevBtnEl)
            if (nextBtnEl) rightContainer.appendChild(nextBtnEl)

            footerEl.innerHTML = ''
            footerEl.appendChild(leftContainer)
            footerEl.appendChild(rightContainer)
          }

          // 3. 状态更新
          const isLastStep = state.activeIndex === (config.steps?.length ?? 0) - 1
          const activeNextBtn = nextButton || footerEl.querySelector(`.${CLASS_NEXT_BTN}`)

          if (activeNextBtn) {
             if (isLastStep) {
               activeNextBtn.classList.add(CLASS_DONE_BTN)
             } else {
               activeNextBtn.classList.remove(CLASS_DONE_BTN)
             }
          }
        } catch (e) {
          console.error('Onboarding Tour Render Error:', e)
        }
      },

      // 步骤高亮时触发
      onHighlightStarted: async (element, step) => {
        // 清理之前的监听器
        if (currentClickListener) {
          const { element: el, handler, keyHandler, originalTabIndex, eventTypes } = currentClickListener
          // Remove all tracked event types
          if (eventTypes) {
            eventTypes.forEach(type => el.removeEventListener(type, handler))
          }
          if (keyHandler) el.removeEventListener('keydown', keyHandler)
          if (originalTabIndex !== undefined) {
             if (originalTabIndex === null) el.removeAttribute('tabindex')
             else el.setAttribute('tabindex', originalTabIndex)
          }
          currentClickListener = null
        }

        // 尝试等待元素
        if (!element && step.element && typeof step.element === 'string') {
           const exists = await ensureElement(step.element, 8000)
           if (!exists) {
             console.warn(`Tour element not found after 8s: ${step.element}`)
             return
           }
           element = document.querySelector(step.element) as HTMLElement
        }

        const isInteractiveStep = step.popover?.showButtons?.length === 1 &&
                                   step.popover.showButtons[0] === 'close'

        if (isInteractiveStep && element) {
          const htmlElement = element as HTMLElement

          // Check if this is a submit button - if so, don't bind auto-advance listeners
          // Let business code (e.g., handleCreateGroup) manually call nextStep after success
          const isSubmitButton = htmlElement.getAttribute('type') === 'submit' ||
                                (htmlElement.tagName === 'BUTTON' && htmlElement.closest('form'))

          if (isSubmitButton) {
            console.log('Submit button detected, skipping auto-advance listener')
            return // Don't bind any click listeners for submit buttons
          }

          const originalTabIndex = htmlElement.getAttribute('tabindex')
          if (!htmlElement.isContentEditable && htmlElement.tabIndex === -1) {
             htmlElement.setAttribute('tabindex', '0')
          }

          // Enhanced Select component detection - check both children and self
          const isSelectComponent = htmlElement.querySelector('.select-trigger') !== null ||
                                    htmlElement.classList.contains('select-trigger')

          // Single-execution protection flag
          let hasExecuted = false

          const clickHandler = async () => {
            // Prevent duplicate execution
            if (hasExecuted) {
              console.warn('Click handler already executed, skipping')
              return
            }
            hasExecuted = true

            // For Select components, wait longer to allow user to make a selection
            const waitTime = isSelectComponent ? TIMING.SELECT_WAIT_MS : TIMING.INTERACTIVE_WAIT_MS
            await new Promise(resolve => setTimeout(resolve, waitTime))

            // Verify driver is still active and not destroyed
            if (!driverInstance || !driverInstance.isActive()) {
              console.warn('Driver instance destroyed or inactive during navigation')
              return
            }

            const currentIndex = driverInstance.getActiveIndex() ?? 0
            const nextStep = steps[currentIndex + 1]

            if (nextStep?.element && typeof nextStep.element === 'string') {
              // 增加超时时间到 8 秒，给路由导航更多时间
              const exists = await ensureElement(nextStep.element, TIMING.ELEMENT_TIMEOUT_MS)
              if (!exists) {
                console.warn('Next step element not found after timeout, aborting auto-advance')
                console.warn('Expected element:', nextStep.element)
                return
              }
            }

            // Final check before moving
            if (driverInstance && driverInstance.isActive()) {
              driverInstance.moveNext()
            }
          }

          // For input fields, advance on input/change events instead of click
          const isInputField = ['INPUT', 'TEXTAREA', 'SELECT'].includes(htmlElement.tagName)

          if (isInputField) {
            const inputHandler = () => {
              // Remove listener after first input
              htmlElement.removeEventListener('input', inputHandler)
              htmlElement.removeEventListener('change', inputHandler)
              clickHandler()
            }

            htmlElement.addEventListener('input', inputHandler)
            htmlElement.addEventListener('change', inputHandler)

            currentClickListener = {
              element: htmlElement,
              handler: inputHandler,
              originalTabIndex,
              eventTypes: ['input', 'change']
            }
          } else if (isSelectComponent) {
            // For Select components, listen for option selection clicks
            const selectOptionClickHandler = (e: Event) => {
              const target = e.target as HTMLElement
              // Type safety: ensure target is an Element before using closest
              if (!(target instanceof Element)) {
                return
              }
              // Check if the clicked element is a select option
              if (target.closest('.select-option')) {
                // User selected an option, proceed to next step
                clickHandler()
              }
            }

            const keyHandler = (e: KeyboardEvent) => {
               if (['Enter', ' '].includes(e.key)) {
                  e.preventDefault()
                  // For select components, Enter/Space should open dropdown, not advance
                  // Only advance if an option is focused
                  const focusedOption = htmlElement.querySelector('.select-option:focus')
                  if (focusedOption) {
                    clickHandler()
                  }
               }
            }

            htmlElement.addEventListener('click', selectOptionClickHandler)
            htmlElement.addEventListener('keydown', keyHandler)

            currentClickListener = {
              element: htmlElement,
              handler: selectOptionClickHandler as () => void,
              keyHandler,
              originalTabIndex,
              eventTypes: ['click']
            }
          } else {
            const keyHandler = (e: KeyboardEvent) => {
               if (['Enter', ' '].includes(e.key)) {
                  e.preventDefault()
                  clickHandler()
               }
            }

            htmlElement.addEventListener('click', clickHandler, { once: true })
            htmlElement.addEventListener('keydown', keyHandler)

            currentClickListener = {
              element: htmlElement,
              handler: clickHandler as () => void,
              keyHandler,
              originalTabIndex,
              eventTypes: ['click']
            }
          }
        }
      },

      onDestroyed: () => {
        if (currentClickListener) {
          const { element: el, handler, keyHandler, originalTabIndex, eventTypes } = currentClickListener
          // Remove all tracked event types
          if (eventTypes) {
            eventTypes.forEach(type => el.removeEventListener(type, handler))
          }
          if (keyHandler) el.removeEventListener('keydown', keyHandler)
          if (originalTabIndex !== undefined) {
             if (originalTabIndex === null) el.removeAttribute('tabindex')
             else el.setAttribute('tabindex', originalTabIndex)
          }
          currentClickListener = null
        }
        // 清理全局监听器 (由此处唯一管理)
        if (globalKeyboardHandler) {
          document.removeEventListener('keydown', globalKeyboardHandler, { capture: true })
          globalKeyboardHandler = null
        }
        onboardingStore.setDriverInstance(null)
      }
    })

    onboardingStore.setDriverInstance(driverInstance)

    // 添加全局键盘监听器
    globalKeyboardHandler = (e: KeyboardEvent) => {
      if (!driverInstance?.isActive()) return

      if (e.key === 'Escape') {
        e.preventDefault()
        e.stopPropagation()
        if (confirm(t('onboarding.confirmExit'))) {
          driverInstance.destroy()
          onboardingStore.setDriverInstance(null)
        }
        return
      }

      if (e.key === 'ArrowRight') {
        const target = e.target as HTMLElement
        // 允许在输入框中使用方向键
        if (['INPUT', 'TEXTAREA'].includes(target?.tagName)) {
           return
        }

        e.preventDefault()
        e.stopPropagation()

        // 对于交互式步骤，箭头键应该触发交互而非跳过
        const currentIndex = driverInstance!.getActiveIndex() ?? 0
        const currentStep = steps[currentIndex]
        const isInteractiveStep = currentStep?.popover?.showButtons?.length === 1 &&
                                   currentStep?.popover.showButtons[0] === 'close'

        if (isInteractiveStep && currentStep.element) {
          const targetElement = typeof currentStep.element === 'string'
            ? document.querySelector(currentStep.element) as HTMLElement
            : currentStep.element as HTMLElement

          if (targetElement) {
            // 对于非输入类元素，提示用户需要点击或按Enter
            const isClickable = !['INPUT', 'TEXTAREA', 'SELECT'].includes(targetElement.tagName)
            if (isClickable) {
              // 不自动触发，只是停留提示
              return
            }
          }
        }

        // 非交互式步骤才允许箭头键翻页
        driverInstance!.moveNext()
      }
      else if (e.key === 'Enter') {
        const target = e.target as HTMLElement
        // 允许在输入框中使用回车
        if (['INPUT', 'TEXTAREA'].includes(target?.tagName)) {
           return
        }

        e.preventDefault()
        e.stopPropagation()

        // 回车键处理交互式步骤
        const currentIndex = driverInstance!.getActiveIndex() ?? 0
        const currentStep = steps[currentIndex]
        const isInteractiveStep = currentStep?.popover?.showButtons?.length === 1 &&
                                   currentStep?.popover.showButtons[0] === 'close'

        if (isInteractiveStep && currentStep.element) {
          const targetElement = typeof currentStep.element === 'string'
            ? document.querySelector(currentStep.element) as HTMLElement
            : currentStep.element as HTMLElement

          if (targetElement) {
            const isClickable = !['INPUT', 'TEXTAREA', 'SELECT'].includes(targetElement.tagName)
            if (isClickable) {
              targetElement.click()
              return
            }
          }
        }
        driverInstance!.moveNext()
      }
      else if (e.key === 'ArrowLeft') {
        const target = e.target as HTMLElement
        // 允许在输入框中使用方向键
        if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target?.tagName) || target?.isContentEditable) {
           return
        }

        e.preventDefault()
        e.stopPropagation()
        driverInstance.movePrevious()
      }
    }

    document.addEventListener('keydown', globalKeyboardHandler, { capture: true })
    driverInstance.drive(startIndex)
  }

  const nextStep = async (delay = 300) => {
    if (!driverInstance?.isActive()) return
    if (delay > 0) {
      await new Promise(resolve => setTimeout(resolve, delay))
    }
    driverInstance.moveNext()
  }

  const isCurrentStep = (elementSelector: string): boolean => {
    if (!driverInstance?.isActive()) return false
    const activeElement = driverInstance.getActiveElement()
    return activeElement?.matches(elementSelector) ?? false
  }

  const replayTour = () => {
    clearSeen()
    void startTour()
  }

  onMounted(async () => {
    onboardingStore.setControlMethods({
      nextStep,
      isCurrentStep
    })

    if (onboardingStore.isDriverActive()) {
      console.log('Tour already active, skipping auto-start')
      driverInstance = onboardingStore.getDriverInstance()
      return
    }

    if (!options.autoStart || hasSeen()) return
    autoStartTimer = setTimeout(() => {
      void startTour()
    }, TIMING.AUTO_START_DELAY_MS)
  })

  onBeforeUnmount(() => {
    // 保持 driver 实例活跃，支持路由切换
  })

  onUnmounted(() => {
    if (autoStartTimer) {
      clearTimeout(autoStartTimer)
      autoStartTimer = null
    }
    // 关键修复：不再此处清理 globalKeyboardHandler，交由 driver.onDestroyed 管理
    onboardingStore.clearControlMethods()
  })

  return {
    startTour,
    replayTour,
    nextStep,
    isCurrentStep,
    hasSeen,
    markAsSeen,
    clearSeen
  }
}
