/**
 * 弹窗状态机管理 hook
 *
 * 用于管理 storage-cells-summary 组件的弹窗流程，采用状态机模式控制不同弹窗的显示和转换。
 * 支持以下弹窗状态：
 * 1. 空闲状态 (idle) - 无弹窗显示
 * 2. 密码显示状态 (password-show) - 显示生成的密码
 * 3. 密码验证状态 (password-verify) - 验证用户输入的密码
 * 4. 取出输入状态 (retrieve-input) - 输入取出密码
 * 5. 处理中状态 (processing) - 显示处理中的加载提示
 *
 * 通过状态机模式确保业务流程的完整性，并提供统一的弹窗控制接口。
 */

import { ref, computed, Ref, ComputedRef } from 'vue'

/**
 * 弹窗状态联合类型
 * 定义所有可能的弹窗状态及其携带的数据
 */
export type PopupState =
  | { type: 'idle' }                                    // 空闲状态，无弹窗显示
  | { type: 'password-show', password: string }         // 显示生成的密码
  | { type: 'password-verify', correctPassword: string } // 密码验证输入
  | { type: 'retrieve-input' }                          // 取出密码输入
  | { type: 'processing', action: 'deposit' | 'retrieve' } // 处理中状态

/**
 * usePopupState hook 返回值接口
 * 定义 hook 返回的所有状态变量和函数的类型
 */
export interface UsePopupStateReturn {
  /** 当前弹窗状态，通过 ref 管理以便响应式更新 */
  currentState: Ref<PopupState>
  /** 弹窗输入框的值，用于密码验证和取出流程 */
  popupInputValue: Ref<string>
  /** 密码长度，固定为 4 位 */
  passwordLength: number
  /** 弹窗显示状态，根据当前状态自动计算 */
  popupVisible: ComputedRef<boolean>
  /** 键盘显示状态 */
  keyboardVisible: Ref<boolean>
  /** 弹窗标题，根据当前状态自动计算 */
  popupTitle: ComputedRef<string>
  /** 弹窗消息内容，根据当前状态自动计算 */
  popupMessage: ComputedRef<string>
  /** 确认按钮文本，根据当前状态自动计算 */
  popupConfirmText: ComputedRef<string>
  /** 是否显示取消按钮，根据当前状态自动计算 */
  showCancelButton: ComputedRef<boolean>
  /** 状态转换函数，用于切换弹窗状态 */
  transitionTo: (state: PopupState) => void
  /** 密码输入变化处理函数 */
  handlePasswordInputChange: (value: string) => void
  /** 弹窗取消/关闭处理函数 */
  handlePopupCancel: () => void
  /** 键盘输入处理函数 */
  handleKeyboardInput: (key: string) => void
  /** 键盘删除处理函数 */
  handleKeyboardDelete: () => void
  /** 键盘关闭处理函数 */
  handleKeyboardClose: () => void
}

/**
 * 弹窗状态机管理 hook
 *
 * 提供弹窗状态管理、状态转换、弹窗内容计算等功能
 * 使用状态机模式确保业务流程的完整性和一致性
 *
 * @returns {UsePopupStateReturn} 弹窗状态管理对象，包含状态变量和控制函数
 */
export function usePopupState(): UsePopupStateReturn {
  // 当前弹窗状态，初始化为空闲状态
  const currentState = ref<PopupState>({ type: 'idle' })
  // 弹窗输入框的值，用于密码输入验证
  const popupInputValue = ref('')
  // 键盘显示状态
  const keyboardVisible = ref(false)
  // 密码长度，固定为 4 位数字密码
  const passwordLength = 4

  /**
   * 状态转换函数
   *
   * 切换当前弹窗状态，并在需要时重置输入值
   *
   * @param {PopupState} state - 要切换到的目标状态
   */
  function transitionTo(state: PopupState) {
    currentState.value = state

    // 控制键盘显示状态
    if (state.type === 'password-verify' || state.type === 'retrieve-input') {
      // 进入需要输入密码的状态时显示键盘
      keyboardVisible.value = true
      // 重置输入值当进入需要输入的弹窗（密码验证或取出输入）
      popupInputValue.value = ''
    } else {
      // 其他状态隐藏键盘
      keyboardVisible.value = false
    }
  }

  /**
   * 弹窗显示状态计算属性
   *
   * 只要当前状态不是空闲状态，就显示弹窗
   */
  const popupVisible = computed(() => currentState.value.type !== 'idle')

  /**
   * 弹窗标题计算属性
   *
   * 根据当前状态返回相应的标题文本
   */
  const popupTitle = computed(() => {
    const state = currentState.value
    switch (state.type) {
      case 'password-show': return '密码已生成'
      case 'password-verify': return '密码验证'
      case 'retrieve-input': return '输入密码'
      default: return ''
    }
  })

  /**
   * 弹窗消息内容计算属性
   *
   * 根据当前状态返回相应的消息文本
   * 支持使用 \n 换行符进行换行
   */
  const popupMessage = computed(() => {
    const state = currentState.value
    switch (state.type) {
      case 'password-show': return `请牢记你的暂存密码为：${state.password}\n请确认已打开的柜子，放置物品后将柜子关闭。`
      case 'password-verify': return '请输入刚才显示的密码进行验证'
      case 'retrieve-input': return '请输入格口密码'
      default: return ''
    }
  })

  /**
   * 确认按钮文本计算属性
   *
   * 根据当前状态返回相应的确认按钮文本
   */
  const popupConfirmText = computed(() => {
    const state = currentState.value
    switch (state.type) {
      case 'password-show': return '已记住'
      case 'password-verify': return '验证'
      case 'retrieve-input': return '确认'
      default: return '确认'
    }
  })

  /**
   * 显示取消按钮计算属性
   *
   * 在需要用户输入的状态（密码验证、取出输入）显示取消按钮
   * 允许用户取消当前操作流程
   */
  const showCancelButton = computed(() => {
    const state = currentState.value
    return state.type === 'password-verify' || state.type === 'retrieve-input'
  })

  /**
   * 密码输入变化处理函数
   *
   * 处理密码输入框的变化事件，可以留空或添加额外的业务逻辑
   * 例如：输入时进行实时验证、限制输入格式等
   *
   * @param {string} value - 当前输入的密码值
   */
  function handlePasswordInputChange(value: string) {
    // 密码输入变化处理，可以留空或添加额外逻辑
    // 例如：实时验证密码格式、限制输入长度等
  }

  /**
   * 弹窗取消/关闭处理函数
   *
   * 用户点击取消按钮或关闭弹窗时调用
   * 将状态切换回空闲状态，中断当前操作流程
   */
  function handlePopupCancel() {
    transitionTo({ type: 'idle' })
  }

  /**
   * 键盘输入处理函数
   *
   * 处理键盘按键输入，更新输入值，但不超过最大长度
   *
   * @param {string} key - 输入的按键值
   */
  function handleKeyboardInput(key: string) {
    if (popupInputValue.value.length < passwordLength) {
      popupInputValue.value += key
    }
  }

  /**
   * 键盘删除处理函数
   *
   * 删除最后一位输入
   */
  function handleKeyboardDelete() {
    if (popupInputValue.value.length > 0) {
      popupInputValue.value = popupInputValue.value.slice(0, -1)
    }
  }

  /**
   * 键盘关闭处理函数
   *
   * 关闭键盘，但保持弹窗显示（用户可能点击外部关闭键盘但不想取消操作）
   */
  function handleKeyboardClose() {
    keyboardVisible.value = false
  }

  // 返回弹窗状态管理对象
  return {
    currentState,
    popupInputValue,
    passwordLength,
    popupVisible,
    keyboardVisible,
    popupTitle,
    popupMessage,
    popupConfirmText,
    showCancelButton,
    transitionTo,
    handlePasswordInputChange,
    handlePopupCancel,
    handleKeyboardInput,
    handleKeyboardDelete,
    handleKeyboardClose
  }
}