import Vue from 'vue'
import { post } from '@vue2-client/services/api/restTools'

/**
 * @typedef {Object} RequestResult
 * @property {boolean} success - 请求是否成功
 * @property {any} data - 响应数据
 * @property {Error|null} error - 错误信息
 */

/**
 * @typedef {Object} UsePostReturn
 * @property {boolean} loading - 加载状态
 * @property {Error|null} error - 错误信息
 * @property {any} data - 响应数据
 * @property {(params?: object, config?: object) => Promise<RequestResult>} execute - 执行请求
 * @property {() => void} reset - 重置状态
 */

/**
 * Vue Composition API 风格的 POST 请求 Hook
 * 提供响应式的 loading 状态管理，返回统一的结果结构
 *
 * @param {string} url - 请求地址
 * @param {object} defaultConfig - 默认配置
 * @param {boolean|string} defaultConfig.globalLoading - 是否显示全局 Loading
 * @param {boolean} defaultConfig.showErrorMessage - 业务 code 500 及其他非 200（不含 601）时是否显示默认错误提示（默认 true），设为 false 时由业务自行处理
 * @param {boolean} defaultConfig.dedupe - 是否启用请求去重（POST 默认开启，设为 false 可关闭）
 * @returns {UsePostReturn}
 *
 * @example
 * // 基础用法
 * const { loading, execute } = usePost('/api/save')
 * const { success, data, error } = await execute(formData)
 * if (success) {
 *   message.success('保存成功')
 * }
 *
 * @example
 * // 在模板中绑定 loading 状态
 * // <a-button :loading="loading" @click="handleSave">保存</a-button>
 * const { loading, execute } = usePost('/api/save', { globalLoading: '保存中...' })
 *
 * @example
 * // 获取响应式数据
 * const { loading, data, error, execute } = usePost('/api/query')
 * await execute({ id: 1 })
 * // data 会自动更新，可直接在模板中使用
 */
export function usePost(url, defaultConfig = {}) {
  // 响应式状态
  const state = Vue.observable({
    loading: false,
    error: null,
    data: null
  })

  /**
   * 执行请求
   * @param {object} params - 请求参数
   * @param {object} config - 本次请求的配置（覆盖默认配置）
   * @returns {Promise<RequestResult>} 统一的结果结构
   */
  async function execute(params = {}, config = {}) {
    state.loading = true
    state.error = null

    try {
      const result = await post(url, params, { ...defaultConfig, ...config })
      state.data = result
      return { success: true, data: result, error: null }
    } catch (err) {
      state.error = err
      return { success: false, data: null, error: err }
    } finally {
      state.loading = false
    }
  }

  /**
   * 重置状态
   */
  function reset() {
    state.loading = false
    state.error = null
    state.data = null
  }

  // 返回响应式属性的 getter，确保在模板中能正确响应
  return {
    get loading() {
      return state.loading
    },
    get error() {
      return state.error
    },
    get data() {
      return state.data
    },
    execute,
    reset
  }
}

export default usePost

/**
 * @typedef {Object} UseRunLogicReturn
 * @property {boolean} loading - 加载状态
 * @property {Error|null} error - 错误信息
 * @property {any} data - 响应数据
 * @property {(params?: object, overrideOptions?: object) => Promise<RequestResult>} execute - 执行请求
 * @property {() => void} reset - 重置状态
 */

/**
 * Vue Composition API 风格的 runLogic Hook
 * 用于调用后端业务逻辑，提供响应式的 loading 状态管理
 *
 * @param {string} logicName - 业务逻辑名称
 * @param {object} options - 配置选项
 * @param {string} options.serviceName - 服务名称，默认为 VUE_APP_SYSTEM_NAME
 * @param {boolean} options.isDev - 是否为开发环境
 * @param {boolean|string} options.globalLoading - 是否显示全局 Loading
 * @param {boolean} options.dedupe - 是否启用请求去重（POST 默认开启，设为 false 可关闭）
 * @param {boolean} options.showErrorMessage - 业务 code 500 及其他非 200（不含 601）时是否显示默认错误提示（默认 true），设为 false 时由业务自行处理
 * @returns {UseRunLogicReturn}
 *
 * @example
 * // 基础用法
 * const { loading, execute, data } = useRunLogic('getUserInfo')
 * const { success, data: result } = await execute({ userId: 1 })
 * if (success) {
 *   console.log(result)
 * }
 *
 * @example
 * // 带全局 Loading
 * const { loading, execute } = useRunLogic('saveOrder', {
 *   globalLoading: '保存中...',
 *   dedupe: true
 * })
 * // 模板: <a-button :loading="loading" @click="handleSave">保存</a-button>
 *
 * @example
 * // 指定服务名称
 * const { execute } = useRunLogic('queryData', {
 *   serviceName: 'af-custom',
 *   isDev: false
 * })
 */
export function useRunLogic(logicName, options = {}) {
  const {
    serviceName = process.env.VUE_APP_SYSTEM_NAME,
    isDev = false,
    globalLoading = false,
    dedupe = false,
    showErrorMessage = true
  } = options

  // 响应式状态
  const state = Vue.observable({
    loading: false,
    error: null,
    data: null
  })

  /**
   * 构建请求 URL
   * @param {string} svcName - 服务名称
   * @param {boolean} dev - 是否开发环境
   * @returns {string}
   */
  function buildUrl(svcName, dev) {
    const apiPre = dev ? '/devApi/' : '/api/'
    return `${apiPre}${svcName}/logic/${logicName}`
  }

  /**
   * 执行业务逻辑
   * @param {object} params - 请求参数
   * @param {object} overrideOptions - 本次请求的配置（覆盖默认配置）
   * @returns {Promise<RequestResult>} 统一的结果结构
   */
  async function execute(params = {}, overrideOptions = {}) {
    state.loading = true
    state.error = null

    // 合并配置
    const finalServiceName = overrideOptions.serviceName || serviceName
    const finalIsDev = overrideOptions.isDev !== undefined ? overrideOptions.isDev : isDev

    // 构建请求 URL
    const url = buildUrl(finalServiceName, finalIsDev)

    // 构建请求配置
    const requestConfig = {
      globalLoading: overrideOptions.globalLoading !== undefined ? overrideOptions.globalLoading : globalLoading,
      dedupe: overrideOptions.dedupe !== undefined ? overrideOptions.dedupe : dedupe,
      showErrorMessage:
        overrideOptions.showErrorMessage !== undefined ? overrideOptions.showErrorMessage : showErrorMessage
    }

    try {
      const result = await post(url, params, requestConfig)
      state.data = result
      return { success: true, data: result, error: null }
    } catch (err) {
      state.error = err
      return { success: false, data: null, error: err }
    } finally {
      state.loading = false
    }
  }

  /**
   * 重置状态
   */
  function reset() {
    state.loading = false
    state.error = null
    state.data = null
  }

  return {
    get loading() {
      return state.loading
    },
    get error() {
      return state.error
    },
    get data() {
      return state.data
    },
    execute,
    reset
  }
}
