/**
 * 全局加载状态管理器
 */

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

// 加载状态类型
export interface LoadingState {
  key: string
  message?: string
  target?: string | HTMLElement
  background?: string
  customClass?: string
}

// 加载管理器类
class LoadingManager {
  private loadingStates = ref(new Map<string, LoadingState>())
  private loadingInstances = new Map<string, LoadingInstance>()

  /**
   * 开始加载
   */
  start(key: string, options?: Partial<LoadingState>): void {
    const loadingState: LoadingState = {
      key,
      message: options?.message || '加载中...',
      target: options?.target,
      background: options?.background || 'rgba(0, 0, 0, 0.7)',
      customClass: options?.customClass
    }

    this.loadingStates.value.set(key, loadingState)

    // 创建 Element Plus Loading 实例
    const loadingInstance = ElLoading.service({
      target: loadingState.target || 'body',
      text: loadingState.message,
      background: loadingState.background,
      customClass: loadingState.customClass
    })

    this.loadingInstances.set(key, loadingInstance)
  }

  /**
   * 停止加载
   */
  stop(key: string): void {
    const loadingInstance = this.loadingInstances.get(key)
    if (loadingInstance) {
      loadingInstance.close()
      this.loadingInstances.delete(key)
    }

    this.loadingStates.value.delete(key)
  }

  /**
   * 停止所有加载
   */
  stopAll(): void {
    this.loadingInstances.forEach((instance) => {
      instance.close()
    })
    this.loadingInstances.clear()
    this.loadingStates.value.clear()
  }

  /**
   * 检查是否正在加载
   */
  isLoading(key?: string): boolean {
    if (key) {
      return this.loadingStates.value.has(key)
    }
    return this.loadingStates.value.size > 0
  }

  /**
   * 获取加载状态
   */
  getLoadingState(key: string): LoadingState | undefined {
    return this.loadingStates.value.get(key)
  }

  /**
   * 获取所有加载状态
   */
  getAllLoadingStates(): LoadingState[] {
    return Array.from(this.loadingStates.value.values())
  }

  /**
   * 包装异步函数，自动管理加载状态
   */
  wrap<T extends (...args: any[]) => Promise<any>>(
    fn: T,
    key: string,
    options?: Partial<LoadingState>
  ): T {
    return ((...args: any[]) => {
      this.start(key, options)
      return fn(...args)
        .finally(() => {
          this.stop(key)
        })
    }) as T
  }

  /**
   * 创建响应式的加载状态
   */
  createReactiveState(key: string) {
    return {
      isLoading: computed(() => this.isLoading(key)),
      start: (options?: Partial<LoadingState>) => this.start(key, options),
      stop: () => this.stop(key),
      wrap: <T extends (...args: any[]) => Promise<any>>(
        fn: T,
        options?: Partial<LoadingState>
      ) => this.wrap(fn, key, options)
    }
  }
}

// 创建全局加载管理器实例
export const loadingManager = new LoadingManager()

// 便捷方法
export const startLoading = (key: string, options?: Partial<LoadingState>) => {
  loadingManager.start(key, options)
}

export const stopLoading = (key: string) => {
  loadingManager.stop(key)
}

export const isLoading = (key?: string) => {
  return loadingManager.isLoading(key)
}

// 装饰器函数，用于自动管理加载状态
export const withLoading = (
  key: string,
  options?: Partial<LoadingState>
) => {
  return <T extends (...args: any[]) => Promise<any>>(
    target: any,
    _propertyName: string,
    descriptor: TypedPropertyDescriptor<T>
  ) => {
    const method = descriptor.value!
    descriptor.value = ((...args: any[]) => {
      startLoading(key, options)
      return method.apply(target, args).finally(() => {
        stopLoading(key)
      })
    }) as T
  }
}

// 创建带加载状态的异步函数
export const createLoadingFunction = <T extends (...args: any[]) => Promise<any>>(
  fn: T,
  key: string,
  options?: Partial<LoadingState>
): T => {
  return loadingManager.wrap(fn, key, options)
}

// Vue 组合式函数
export const useLoading = (key: string) => {
  return loadingManager.createReactiveState(key)
}

// 常用的加载状态键
export const LoadingKeys = {
  // 全局加载
  GLOBAL: 'global',
  
  // 页面加载
  PAGE_INIT: 'page-init',
  
  // API 请求
  API_REQUEST: 'api-request',
  USER_LIST: 'user-list',
  USER_CREATE: 'user-create',
  USER_UPDATE: 'user-update',
  USER_DELETE: 'user-delete',
  
  POSITION_LIST: 'position-list',
  POSITION_CREATE: 'position-create',
  POSITION_UPDATE: 'position-update',
  POSITION_DELETE: 'position-delete',
  
  // 文件操作
  FILE_UPLOAD: 'file-upload',
  FILE_DOWNLOAD: 'file-download',
  
  // 导出操作
  EXPORT_DATA: 'export-data',
  
  // 登录相关
  LOGIN: 'login',
  LOGOUT: 'logout',
  PASSWORD_RESET: 'password-reset',
  
  // 考试相关
  EXAM_SUBMIT: 'exam-submit',
  EXAM_LOAD: 'exam-load'
} as const

export type LoadingKey = typeof LoadingKeys[keyof typeof LoadingKeys]
