import { indexedDB } from '@vue2-client/utils/indexedDB'
import notification from 'ant-design-vue/lib/notification'
import message from 'ant-design-vue/lib/message'
import { blobValidate } from '@vue2-client/utils/common'
import errorCode from '@vue2-client/utils/errorCode'
import { saveAs } from 'file-saver'
import { post, del } from '@vue2-client/services/api/restTools'

const commonApi = {
  // 获取配置
  getConfig: 'logic/openapi/getLiuliConfiguration',
  // 获取原生配置
  getNativeConfig: 'logic/openapi/getLiuliNativeConfiguration',
  // 配置解析
  parseConfig: 'logic/parseConfig',
  // 通用查询
  query: 'logic/commonQuery',
  // 通用查询全部
  queryAll: 'logic/commonQueryAll',
  // 通用汇总查询
  querySummary: 'logic/commonSummaryQuery',
  // 通用获取图表数据查询
  queryChartsData: 'logic/commonQueryChartsData',
  // 表单查询
  queryWithResource: 'logic/commonQueryWithResource',
  // 通用新增/修改
  addOrModify: 'logic/commonAddOrModify',
  // 通用删除
  delete: 'logic/commonDelete',
  // 通用行保存
  editRowSave: 'logic/commonEditRowSave',
  // 导入数据
  importData: 'crud/importDataByExcel',
  // 导出数据
  exportData: 'logic/commonExport',
  // 导入模板下载
  downloadImportTemplate: 'logic/commonDownloadImportTemplate',
  // 下载数据
  download: 'resource/download',
  // 通用上传
  upload: 'resource/upload',
  // 文件实体操作
  fileEntity: 'entity/t_files',
  // 获取表格列配置
  getColumnsJson: '/api/af-system/logic/getColumns',
  //  v4文件删除
  deleteFile: 'resource/delete',
  // 获取所有用户信息
  getAllUserOptionList: '/api/af-system/logic/getAllUserOptionList'
}

/**
 * 获取字典键参数
 */
export function getDictionaryParam(isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + 'af-system/logic/getDictionaryParam', {})
}

/**
 * 根据配置名获取配置内容
 * @param content 已有的配置内容
 * @param configName 配置名称
 * @param serviceName 命名空间名称
 * @param callback 回调函数
 * @param isDev 是否为开发环境
 */
export function getConfig(content, configName, serviceName = process.env.VUE_APP_SYSTEM_NAME, callback, isDev) {
  if (content) {
    return content
  }
  if (!configName) {
    message.warning('配置名称不能为空')
    return '配置名称不能为空'
  }
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  if (!serviceName) {
    serviceName = process.env.VUE_APP_SYSTEM_NAME
  }
  const getConfigUrl = apiPre + serviceName + '/' + commonApi.getConfig
  indexedDB.getByWeb(configName, getConfigUrl, { configName: configName }, callback)
}

export function getConfigByName(configName, serviceName = process.env.VUE_APP_SYSTEM_NAME, callback, isDev) {
  return getConfig(undefined, configName, serviceName, callback, isDev)
}

export async function getConfigByNameAsync(configName, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  return new Promise((resolve, reject) => {
    try {
      return getConfig(undefined, configName, serviceName, resolve, isDev)
    } catch (e) {
      reject(e)
    }
  })
}

/**
 * 根据配置名获取前端 Logic 配置（不触发服务端解析/编译）
 * 用于 $runFrontLogic 拉取逻辑时传 shouldParseConfig: false
 * @param configName 配置名称（Logic 名称）
 * @param serviceName 命名空间
 * @param isDev 是否开发环境
 */
export async function getLogicConfigByNameAsync(configName, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  if (!configName) {
    return Promise.resolve(null)
  }
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  if (!serviceName) {
    serviceName = process.env.VUE_APP_SYSTEM_NAME
  }
  const getConfigUrl = apiPre + serviceName + '/' + commonApi.getConfig
  return new Promise((resolve, reject) => {
    try {
      indexedDB.getByWeb(configName, getConfigUrl, { configName: configName, shouldParseConfig: false }, resolve)
    } catch (e) {
      reject(e)
    }
  })
}

export function getNativeConfig(configName, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  const getConfigUrl = apiPre + serviceName + '/' + commonApi.getNativeConfig
  return post(getConfigUrl, { configName: configName })
}

/**
 * 调用Logic获取配置内容
 * @param logicName Logic名称
 * @param parameter Logic调用参数
 * @param serviceName 命名空间名称
 * @param callback 回调函数
 * @param isDev 是否是开发环境
 */
export function getConfigByLogic(logicName, parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, callback, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  indexedDB.getByWeb(
    `${logicName}_${JSON.stringify(parameter)}`,
    apiPre + serviceName + '/logic/' + logicName,
    parameter,
    callback
  )
}

/**
 * 配置解析
 * @deprecated 这个函数应该只有琉璃中心会使用，其他项目不能使用 之后会删除这个
 * @param configContent 原配置内容
 * @param configType 配置类型
 */
export function parseConfig(configContent, configType) {
  return post('/api/af-liuli/logic/openapi/parseConfigByClient', {
    configType: configType,
    configContent: configContent
  })
}

/**
 * 通用执行业务逻辑
 * @param {string} logicName - 业务逻辑名称
 * @param {object} parameter - 请求参数
 * @param {string} serviceName - 服务名称
 * @param {boolean} isDev - 是否开发环境
 * @param {object} config - 请求配置
 * @param {boolean} config.dedupe - 是否启用去重（默认 true）
 * @param {string} config.dedupeStrategy - 去重策略：'reject'（拒绝）或 'reuse'（复用结果）
 * @param {boolean|string} config.globalLoading - 是否显示全局 Loading
 * @param {boolean} config.showErrorMessage - 业务 code 500 及其他非 200（不含 601）时是否显示默认错误提示（默认 true），设为 false 时由业务自行处理
 */
export function runLogic(logicName, parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev, config = {}) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/logic/' + logicName, parameter, config)
}

/**
 * 通用查询
 */
export function query(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.query, parameter, { dedupe: false })
}

/**
 * 通用查询全部数据
 */
export function queryAll(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.queryAll, parameter, { dedupe: false })
}

/**
 * 通用获取图表数据
 */
export function queryChartsData(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.queryChartsData, parameter, { dedupe: false })
}

/**
 * 通用汇总查询
 */
export function querySummary(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.querySummary, parameter, { dedupe: false })
}

/**
 * 通用表单查询
 */
export function queryWithResource(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.queryWithResource, parameter, { dedupe: false })
}

/**
 * 通用新增/修改
 */
export function addOrModify(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.addOrModify, parameter)
}

/**
 * 通用删除
 */
export function remove(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.delete, parameter)
}

/**
 * 通用行保存
 */
export function editRowSave(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.editRowSave, parameter)
}

/**
 * 通用导入
 */
export function importData(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.importData, parameter)
}

/**
 * 异步导出
 */

/**
 * 通用导出
 */
export function exportData(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.exportData, parameter, { dedupe: false })
}

/**
 * 通用上传
 */
export function upload(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, config, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.upload, parameter, config)
}

/**
 * 通用导入模板下载
 */
export function downloadImportExcel(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return post(apiPre + serviceName + '/' + commonApi.downloadImportTemplate, parameter, { dedupe: false })
}

// 通用下载
export function download(parameter, filename, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  const notificationKey = 'download'
  notification.open({
    key: notificationKey,
    message: '正在下载数据，请稍候',
    duration: null,
    icon: h => {
      return h('a-icon', {
        props: {
          type: 'loading'
        }
      })
    }
  })
  return post(apiPre + serviceName + '/' + commonApi.download, parameter, {
    responseType: 'blob'
  })
    .then(async data => {
      const isLogin = await blobValidate(data)
      if (isLogin) {
        const blob = new Blob([data])
        saveAs(blob, filename)
        message.success('下载成功')
      } else {
        const resText = await data.text()
        const rspObj = JSON.parse(resText)
        const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode.default
        message.error(errMsg)
      }
      notification.close(notificationKey)
    })
    .catch(r => {
      message.error('功能尚未实现，敬请期待！')
      // message.error('下载文件出现错误，请联系管理员！')
      notification.close(notificationKey)
    })
}

// v3文件删除
export function fileDelete(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return del(apiPre + serviceName + '/' + commonApi.fileEntity + '/' + parameter.id)
}
// v4文件删除
export function fileDeleteV4(parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev) {
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  return del(apiPre + serviceName + '/' + commonApi.deleteFile, parameter)
}

export { commonApi }
