/**
 * 加载状态管理组合式函数
 */

import { ref, computed } from 'vue'
import { ElLoading } from 'element-plus'
import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading'

// 全局加载状态
const globalLoading = ref(false)
const loadingCount = ref(0)

/**
 * 使用加载状态
 */
export const useLoading = (initialState = false) => {
  const loading = ref(initialState)
  
  /**
   * 设置加载状态
   */
  const setLoading = (state: boolean) => {
    loading.value = state
  }

  /**
   * 开始加载
   */
  const startLoading = () => {
    loading.value = true
  }

  /**
   * 结束加载
   */
  const stopLoading = () => {
    loading.value = false
  }

  /**
   * 异步操作包装器
   */
  const withLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
    try {
      startLoading()
      return await fn()
    } finally {
      stopLoading()
    }
  }

  return {
    loading: computed(() => loading.value),
    setLoading,
    startLoading,
    stopLoading,
    withLoading
  }
}

/**
 * 使用全局加载状态
 */
export const useGlobalLoading = () => {
  /**
   * 增加加载计数
   */
  const addLoading = () => {
    loadingCount.value++
    globalLoading.value = true
  }

  /**
   * 减少加载计数
   */
  const removeLoading = () => {
    loadingCount.value = Math.max(0, loadingCount.value - 1)
    if (loadingCount.value === 0) {
      globalLoading.value = false
    }
  }

  /**
   * 重置加载状态
   */
  const resetLoading = () => {
    loadingCount.value = 0
    globalLoading.value = false
  }

  /**
   * 全局异步操作包装器
   */
  const withGlobalLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
    try {
      addLoading()
      return await fn()
    } finally {
      removeLoading()
    }
  }

  return {
    globalLoading: computed(() => globalLoading.value),
    loadingCount: computed(() => loadingCount.value),
    addLoading,
    removeLoading,
    resetLoading,
    withGlobalLoading
  }
}

/**
 * 使用页面加载遮罩
 */
export const usePageLoading = () => {
  let loadingInstance: LoadingInstance | null = null

  /**
   * 显示页面加载遮罩
   */
  const showPageLoading = (options?: {
    text?: string
    background?: string
    target?: string | HTMLElement
  }) => {
    const {
      text = '加载中...',
      background = 'rgba(0, 0, 0, 0.7)',
      target = 'body'
    } = options || {}

    loadingInstance = ElLoading.service({
      lock: true,
      text,
      background,
      target
    })
  }

  /**
   * 隐藏页面加载遮罩
   */
  const hidePageLoading = () => {
    if (loadingInstance) {
      loadingInstance.close()
      loadingInstance = null
    }
  }

  /**
   * 页面异步操作包装器
   */
  const withPageLoading = async <T>(
    fn: () => Promise<T>,
    options?: {
      text?: string
      background?: string
      target?: string | HTMLElement
    }
  ): Promise<T> => {
    try {
      showPageLoading(options)
      return await fn()
    } finally {
      hidePageLoading()
    }
  }

  return {
    showPageLoading,
    hidePageLoading,
    withPageLoading
  }
}

/**
 * 使用按钮加载状态
 */
export const useButtonLoading = () => {
  const buttonLoadings = ref<Record<string, boolean>>({})

  /**
   * 设置按钮加载状态
   */
  const setButtonLoading = (key: string, loading: boolean) => {
    buttonLoadings.value[key] = loading
  }

  /**
   * 获取按钮加载状态
   */
  const getButtonLoading = (key: string) => {
    return computed(() => buttonLoadings.value[key] || false)
  }

  /**
   * 按钮异步操作包装器
   */
  const withButtonLoading = async <T>(
    key: string,
    fn: () => Promise<T>
  ): Promise<T> => {
    try {
      setButtonLoading(key, true)
      return await fn()
    } finally {
      setButtonLoading(key, false)
    }
  }

  return {
    buttonLoadings: computed(() => buttonLoadings.value),
    setButtonLoading,
    getButtonLoading,
    withButtonLoading
  }
}

/**
 * 使用延迟加载
 */
export const useDelayedLoading = (delay = 300) => {
  const loading = ref(false)
  const actualLoading = ref(false)
  let timer: NodeJS.Timeout | null = null

  /**
   * 设置加载状态（带延迟）
   */
  const setLoading = (state: boolean) => {
    if (state) {
      // 立即设置实际加载状态
      actualLoading.value = true
      
      // 延迟显示加载UI
      timer = setTimeout(() => {
        loading.value = true
      }, delay)
    } else {
      // 立即隐藏加载UI
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      loading.value = false
      actualLoading.value = false
    }
  }

  /**
   * 延迟异步操作包装器
   */
  const withDelayedLoading = async <T>(fn: () => Promise<T>): Promise<T> => {
    try {
      setLoading(true)
      return await fn()
    } finally {
      setLoading(false)
    }
  }

  return {
    loading: computed(() => loading.value),
    actualLoading: computed(() => actualLoading.value),
    setLoading,
    withDelayedLoading
  }
}
