const fs = require('fs')
const path = require('path')
const startCase = require('lodash.startcase')
const antdMap = require('./antd-map.js')
function pascalCase(str) {
  return startCase(str).replace(/ /g, '')
}

function getProducts(workspace) {
  return fs
    .readdirSync(path.join(workspace, 'src_product'), { withFileTypes: true })
    .filter((dir) => dir.isDirectory())
    .map((dir) => dir.name)
}

function getPrefix(chunkName) {
  // 扩展点不检查前缀
  if (chunkName.includes('_extension-points')) return
  const paths = chunkName.split('-')
  switch (paths[0]) {
    case 'src':
      return 'sd'
    case 'product':
      return paths[1]
    case 'custom':
      return 'xm'
  }
}

function importer(file, workspace) {
  // console.log(file, workspace)
  const content = fs.readFileSync(file).toString()

  // 处理跳过指令
  if (content.indexOf('// sd-skip-auto-import') !== -1) return

  // 只处理引入了_import-components/*.js的文件
  if (content.indexOf("import components from './_import-components/") !== -1) {
    // 检查文件名是否符合命名规范
    const relativePath = path.relative(workspace, path.dirname(file))
    const chunkName = relativePath.replace('src_', '').replace(/(\\|\\\/)/g, '-')
    const prefix = getPrefix(chunkName)
    let fileNameError = ''
    if (prefix) {
      const fileName = path.basename(file)
      if (!fileName.startsWith(prefix)) {
        fileNameError = `console.warn('文件名 ${fileName} 不符合命名规则，应该以 ${prefix} 开头')\n`
      }
    }

    // 获取template的内容
    const template = content.substring(
      content.indexOf('<template>') + 10,
      content.indexOf('\n</template>')
    )
    // 查找范围： sd-xxxxx xm-xxxx a-xxxxx oa-xxxxx
    const prefixes = ['sd', 'xm', 'a', 'ext', ...getProducts(workspace)]
    const regexp = new RegExp(`<(?:${prefixes.join('|')})-[a-z-A-Z]+`, 'g')
    const matched = template.match(regexp)
    const uniqueArray = [...new Set(matched)]
    const tags = uniqueArray.map((tag) => tag.substr(1)).sort()
    // eslint-disable-next-line no-console
    console.log('找到如下组件：')
    // eslint-disable-next-line no-console
    console.log(tags.join(', '))

    let tagsAnt = []
    const tagsSd = []

    tags.forEach((tag) => {
      if (tag.startsWith('a-')) {
        // 去掉a-前缀
        tag = pascalCase(tag.substr(2))
        tagsAnt.push(tag)
      } else if (tag.startsWith('ext-')) {
        // 扩展点
        const pathToSrc = path.relative(path.resolve(workspace, 'src'), file)
        // eslint-disable-next-line no-useless-escape
        const moduleName = pathToSrc.split(/[\\|\/]/)[0]

        tagsSd.push({
          name: pascalCase(tag),
          path: `@extension-points/${moduleName}/${tag}.vue`,
        })
      } else {
        // sd-开头的情况
        let vueDir = path.dirname(file)
        let vueFile
        let findInCurrentModule = false
        let parentLevel = 1
        // 先在当前目录及父目录查找 sd-xxxx.vue，到workspace目录停止
        while (vueDir !== workspace && parentLevel < 10) {
          // 检查本目录和components目录
          const vueFiles = [
            path.resolve(vueDir, tag + '.vue'),
            path.resolve(vueDir, 'components', tag + '.vue'),
          ]
          findInCurrentModule = vueFiles.some((vueFile) => {
            // console.log('检查文件：' + vueFile)

            let relativePath = path.relative(file, vueFile).replace(/\\/g, '/')
            if (relativePath === '') {
              // 递归引用自身，特殊处理一下
              relativePath = '../' + path.basename(vueFile)
            }
            if (fs.existsSync(vueFile)) {
              tagsSd.push({
                name: pascalCase(tag),
                path: relativePath,
              })
              return true
            }
          })
          if (findInCurrentModule) break
          vueDir = path.resolve(vueDir, '..')
          parentLevel++
        }

        if (!findInCurrentModule) {
          // 再去公共组件目录查找 sd-xxxx.vue
          vueFile = path.resolve(workspace, 'src/common/components', tag + '.vue')
          // console.log('检查文件：' + vueFile)
          if (fs.existsSync(vueFile)) {
            tagsSd.push({
              name: pascalCase(tag),
              path: '@/common/components/' + tag + '.vue',
            })
          }
        }
      }
    })
    // antdMap中保存着如下映射关系  "ButtonGroup": "Button"
    // 用于找到ButtonGroup这种组件实际需要导入的内容：Button
    tagsAnt = tagsAnt.map((tag) => antdMap[tag] || tag)
    // 去重并排序
    tagsAnt = [...new Set(tagsAnt)].sort()
    const uses = tagsAnt.map((tag) => `Vue.use(${tag})`)
    // 生成import语句
    const imports = []
    if (tagsAnt.length)
      imports.push(`import Vue from 'vue'
import {
${tagsAnt.join(',\n')},
} from 'ant-design-vue'`)

    tagsSd.forEach((tag) => {
      imports.push(`import ${tag.name} from '${tag.path}'`)
    })
    // _import-components不存在的话，先创建
    const jsPath = path.resolve(path.dirname(file), '_import-components')
    if (!fs.existsSync(jsPath)) fs.mkdirSync(jsPath)

    const jsFile = path.resolve(jsPath, path.basename(file, '.vue') + '-import.js')
    const jsContent =
      `/* eslint-disable import/order */
// 此文件自动生成，不要手工修改
${imports.join('\n')}

${uses.join('\n')}

export default {
  ${tagsSd.map((tag) => tag.name).join(',\n  ')}${tagsSd.length ? ',' : ''}
}
` + fileNameError

    if (fs.existsSync(jsFile)) {
      const jsOld = fs.readFileSync(jsFile).toString()
      if (jsOld === jsContent) {
        // eslint-disable-next-line no-console
        console.log('内容没有发生变化，跳过')
      } else {
        writeFile(jsFile, jsContent)
      }
    } else {
      writeFile(jsFile, jsContent)
    }
  } else {
    // eslint-disable-next-line no-console
    console.log('没有引入 _import-components/*.js，跳过')
  }

  function writeFile(jsFile, jsContent) {
    // 生成最终的js文件
    fs.writeFile(jsFile, jsContent, (error) => {
      if (error) {
        // eslint-disable-next-line no-console
        console.error('Error while creating ' + jsFile)
        throw error
      }
    })
  }
}
module.exports = importer
