const ora = require('ora')
const path = require('path')
const chalk = require('chalk')
const fsEx = require('fs-extra')
const { DOC_ROOT_PATH } = require('../../constant/doc')
const { npm } = require('../../utils/npm')
const {
  STORYBOOK_DIST_PATH,
  PROJECT_DOC_DIST_PATH,
  STORYBOOK_CONFIG_PATH,
} = require('../../constant/doc')
const { mergeConfig } = require('../../utils/doc-methods')
const rimraf = require('rimraf')
const puppeteer = require('puppeteer')

// 封面截图
async function screenshot() {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()

  const configPath = path.join(STORYBOOK_CONFIG_PATH, 'main.js')
  const config = require(configPath)
  if (!config.coverPath) {
    await browser.close()
    return true
  }

  const pageUrl = `file://${PROJECT_DOC_DIST_PATH}/index.html?path=${config.coverPath}`
  await page.goto(pageUrl, { waitUntil: 'domcontentloaded' })

  return new Promise((resolve) => {
    setTimeout(async () => {
      try {
        const elementHandle = await page.waitForSelector(
          '#storybook-preview-iframe',
          {
            timeout: 5 * 1000, // 10s超时
          }
        ) // 等待选择器选中
        const iframe = await elementHandle.contentFrame() // 解析iframe
        const dom = await iframe.waitForSelector('.sb-show-main #root', {
          timeout: 5 * 1000,
        })

        await dom.screenshot({
          path: path.resolve(PROJECT_DOC_DIST_PATH, './ark-cover-shot.png'),
        }) // 截图
        await browser.close()
        resolve(true)
      } catch (e) {
        console.log(e)
        await browser.close()
        resolve(false)
      }
    }, 2000) // 等待页面重定向
  })
}

async function buildDoc() {
  // 打包编译文档
  const spinner = ora('正在编译打包文档，时间较长，请耐心等待...').start()
  spinner.text = ''
  console.log('')

  // 合并storybook配置
  mergeConfig()

  // 执行打包命令
  const { status } = await npm(['run', 'build-storybook'], {
    cwd: DOC_ROOT_PATH,
  })
  if (status !== 0) {
    spinner.fail(
      chalk.red(
        '文档编译失败!编译前请先本地预览下文档，确保本地能够正常预览文档的情况下，再重新执行打包命令'
      )
    )
    return
  }

  // 清理之前的打包产物，然后重新把包复制到项目根路径
  if (fsEx.pathExistsSync(PROJECT_DOC_DIST_PATH)) {
    rimraf.sync(PROJECT_DOC_DIST_PATH)
  }
  fsEx.copySync(STORYBOOK_DIST_PATH, PROJECT_DOC_DIST_PATH)

  // 进行页面截图
  if (await screenshot()) {
    spinner.succeed(chalk.green('编译完成!'))
  } else {
    spinner.fail('编译失败')
  }
}

module.exports = buildDoc
