import { OSS_ENV_PATH } from 'utils/oss'
import inquirer from 'inquirer'
import path from 'path'
import chalk from 'chalk'
import OssInstance from 'utils/oss'
import ora from 'ora'
import {uploadOssCallback,uploadOssDocCallback} from './callback';
import {
  getPackageInfo,
} from 'utils/file'

const fsEx = require('fs-extra')

export interface UploadOssOptions {
  upload: boolean
  ossPath?: string
  name: string
  localPath?: string
  callback: () => void
  [params: string]: string | undefined | boolean | object
}

async function uploadOssList(options: UploadOssOptions) {
  await options.callback()
}

async function confirmUpload(value: string) {
  const canUpload = (
    await inquirer.prompt({
      type: 'confirm',
      name: 'canUpload',
      message: `请确认是否上传到${value}目录下`,
    })
  ).canUpload
  return canUpload
}

async function uploadOSS(options: UploadOssOptions) {
  // 上传到线上时需要提示(即/CDN开头的路径)
  const isPublishToProduct = options.ossPath?.startsWith(options.name)
  if (isPublishToProduct) {
    const isConfirm = await confirmUpload(options.name)
    if (!isConfirm) {
      return
    }
  }

  // 如果用户清除缓存
  if (options.clearCache) {
    fsEx.removeSync(OSS_ENV_PATH)
  }

  await OssInstance.init()
  const ossPath = options.ossPath || ''
  // 生产环境如果已存在oss目录，就不允许上传。防止覆盖
  if(isPublishToProduct) {
    const isExistOssPath = await OssInstance.isExistOssPath(ossPath)
    if (isExistOssPath) {
      console.log(chalk.red(`oss路径${options.ossPath}已存在!请重新指定--ossPath参数`))
      return
    }
  }

  let localPath = ''
  if (options.localPath && options.localPath.startsWith('/')) {
    // 绝对路径
    localPath = options.localPath
  } else {
    localPath = path.resolve(process.cwd(), options.localPath || '')
  }
  const spinner = ora(`正在上传文件至oss目录${ossPath}，请稍等...`).start()
  spinner.text = ''
  const status = await OssInstance.multipleFilesUpload(ossPath, localPath)

  if (!status) {
    fsEx.removeSync(OSS_ENV_PATH) // 清除配置
    spinner.fail(chalk.red('文件上传失败!'))
    return
  }

  // 不发正式版的话就不更新oss列表
  if (!options.ossPath?.startsWith(options.name) && options.name !== './DOC') {
    spinner.succeed(chalk.green('文件上传成功!'))
    return
  }

  // 自动更新oss上的json
  await uploadOssList(options)

  spinner.succeed(chalk.green('文件上传成功!'))
}

function upload(options: UploadOssOptions) {
  // 传参
  if(options.doc){
    // 上传文档
    const packageInfo = getPackageInfo()
    options.ossPath = `/DOC/${packageInfo.name}`;
    options.localPath = './.arkdoc-dist';
    options.callback = uploadOssDocCallback;
    options.name = '/DOC';
  }else{
    // 根据上传目录上传文件
    options.callback = uploadOssCallback;
    options.name = '/CDN';
  }
  uploadOSS(options)
}

export default upload
