const path = require('path')
const fs = require('fs')
const fsEx = require('fs-extra')
const serialize = require('serialize-javascript')
const chalk = require('chalk')
const { beautifyJs } = require('./beautify-file')
const { formatPath } = require('./other')
const { ejsWriteFile } = require('./file')
const {
  PROJECT_DOC_CONFIG_PATH,
  DEFAULT_STORYBOOK_CONFIG_PATH,
  STORYBOOK_CONFIG_PATH,
  DEFAULT_STORYBOOK_WEBPACK_PATH,
  STORYBOOK_WEBPACK_PATH,
} = require('../constant/doc')

// 获取storybook配置
/**
 *
 * @param {String} fileName 文件名称，含后缀
 * @param {String} readWay 读取方式。require:require用读取,read:通过read方式读取
 * @returns
 */
function getDocConfig(fileName, readWay) {
  let projectConfig
  let defaultConfig

  // 获取项目storybook配置

  const projectConfigPath = path.join(PROJECT_DOC_CONFIG_PATH, fileName)
  // 获取默认的storybook配置
  const defaultConfigPath = path.join(DEFAULT_STORYBOOK_CONFIG_PATH, fileName)

  // 没有文件则自动创建
  fsEx.ensureFileSync(defaultConfigPath)

  if (readWay === 'require') {
    projectConfig = require(projectConfigPath)
    defaultConfig = require(defaultConfigPath)
  } else {
    projectConfig = fs.readFileSync(projectConfigPath).toString()
    defaultConfig = fs.readFileSync(defaultConfigPath).toString()
  }
  if (projectConfig.stories) {
    let stories = projectConfig.stories.reduce((arr, item) => {
      arr.push(formatPath(item))
      return arr
    }, [])
    projectConfig.stories = stories
  }

  return {
    defaultConfig,
    projectConfig,
  }
}

// 合并main.js配置
function mergeMainJs(fileName) {
  const { defaultConfig, projectConfig } = getDocConfig(fileName, 'require')

  const newConfig = Object.assign(defaultConfig, projectConfig)

  // 调试
  process.env.debug &&
    console.log(
      chalk.yellow(`debug:main.js配置 ${JSON.stringify(newConfig, null, 2)})}`)
    )

  const targetConfigPath = path.join(STORYBOOK_CONFIG_PATH, fileName)
  const data = beautifyJs(
    `module.exports = ${serialize(newConfig, {
      unsafe: true,
    })}`
  )
  fsEx.outputFileSync(targetConfigPath, data)
}

// 重写storybook配置文件
function overwriteConfig(fileName) {
  const { projectConfig } = getDocConfig(fileName, 'read')

  // 调试
  process.env.debug &&
    console.log(chalk.yellow(`debug:${fileName}配置 ${projectConfig}`))

  const targetConfigPath = path.join(STORYBOOK_CONFIG_PATH, fileName)
  fsEx.outputFileSync(targetConfigPath, projectConfig)
}

// 动态生成webpack配置
function generateWebpack() {
  ejsWriteFile(DEFAULT_STORYBOOK_WEBPACK_PATH, STORYBOOK_WEBPACK_PATH, {
    ROOT_PATH: formatPath(process.cwd()), // 约定指令要在根目录执行，所以这里指的就是项目根路径
  })
}

// 合并storybook配置
function mergeConfig() {
  // 合并main.js配置
  mergeMainJs('main.js')
  // 根据项目路径生成webpack配置
  generateWebpack()
  //重写preview.js配置
  overwriteConfig('preview.js')
  // 重写preview-head.html配置
  overwriteConfig('preview-head.html')
  // 重写preview-body.html配置
  overwriteConfig('preview-body.html')
}

module.exports = {
  mergeConfig,
}
