import path from 'node:path'
import tailwindCss from 'tailwindcss'
import fg from 'fast-glob'
import fs from 'fs-extra'

// 删除构建后一些无用的静态资源
export const delStaticPlugin = () => {
  let config
  return {
    name: 'inline-plugin-del-static',
    apply: 'build',
    configResolved(_config) {
      config = _config
    },
    async closeBundle() {
      const targetPath = path.join(config.build.outDir, '@demos')
      const files = await fg(['**/*.spec.js', '**/*.spec.ts'], {
        dot: true,
        cwd: targetPath
      })
      files.forEach((filename) => {
        const filePath = path.join(targetPath, filename)
        fs.unlink(filePath)
      })
    }
  }
}

// 修改@docsearch依赖,使其支持内外网官网
export const viteDocsearchPlugin = (env) => {
  return {
    name: 'vite-docsearch-plugin',
    enforce: 'pre',
    transform(code, id) {
      if (id.includes('@docsearch')) {
        const newCode = code.replace(
          'Promise((function(t){var n=new XMLHttpRequest;',
          'Promise((function(t){t=window.handleGlobalSearchData(t);var n=new XMLHttpRequest;'
        )
        return {
          code: newCode,
          map: null
        }
      }
    }
  }
}

// 修复 @opentiny/vue-icon 和 @opentiny/vue-icon-saas 的解析问题
// 确保图标包指向 index.ts 而不是 src 目录
// 根据 package.json 的 exports 配置,"./*": "./src/*" 会将某些导入解析为目录
// 这个插件拦截该导入并重定向到 index.ts
const createFixIconSrcPlugin = (packageName, packagePath, pluginName) => {
  const currentFileUrl = import.meta.url
  const currentDir = path.dirname(new URL(currentFileUrl).pathname)
  const normalizedDir = process.platform === 'win32' ? currentDir.replace(/^\//, '') : currentDir
  const workspaceRoot = path.resolve(normalizedDir, '../..')
  const iconSrcPath = path.resolve(workspaceRoot, packagePath, 'src')
  const iconIndexPath = path.resolve(workspaceRoot, packagePath, 'index.ts')

  return {
    name: pluginName,
    enforce: 'pre',
    resolveId(id) {
      // 拦截对包名的导入(不带子路径),确保指向 index.ts
      if (id === packageName) {
        return iconIndexPath
      }
      // 拦截对 @opentiny/vue-icon-saas/src 的导入(模块路径)
      if (id === `${packageName}/src`) {
        return iconIndexPath
      }
      // 拦截文件系统路径中的图标包/src 目录访问
      const normalizedId = id.replace(/\\/g, '/')
      const normalizedSrcPath = iconSrcPath.replace(/\\/g, '/')
      if (normalizedId === normalizedSrcPath) {
        return iconIndexPath
      }
      return null
    },
    load(id) {
      // 如果请求的是图标包/src 目录,返回 index.ts 的内容
      const normalizedId = id.replace(/\\/g, '/')
      const normalizedSrcPath = iconSrcPath.replace(/\\/g, '/')
      if (normalizedId === normalizedSrcPath) {
        if (fs.existsSync(iconIndexPath)) {
          return fs.readFileSync(iconIndexPath, 'utf-8')
        }
      }
      return null
    }
  }
}

// 修复 @opentiny/vue-icon 和 @opentiny/vue-icon-saas 的解析问题
// 返回包含两个插件的数组,方便在 vite.config.ts 中使用
export const fixIconSrcPlugins = () => {
  return [
    createFixIconSrcPlugin('@opentiny/vue-icon', 'packages/vue-icon', 'fix-icon-src-plugin'),
    createFixIconSrcPlugin('@opentiny/vue-icon-saas', 'packages/vue-icon-saas', 'fix-icon-saas-src-plugin')
  ]
}

// 保持向后兼容,单独导出(如果需要单独使用)
export const fixIconSrcPlugin = () => {
  return createFixIconSrcPlugin('@opentiny/vue-icon', 'packages/vue-icon', 'fix-icon-src-plugin')
}

export const fixIconSaasSrcPlugin = () => {
  return createFixIconSrcPlugin('@opentiny/vue-icon-saas', 'packages/vue-icon-saas', 'fix-icon-saas-src-plugin')
}

// 针对不同主题对配置进行响应修改
const themeModifyMap = {
  saas(viteConfig) {
    viteConfig.css = {
      postcss: {
        plugins: [tailwindCss]
      }
    }

    viteConfig.tinyCustom.copyTarget.push({
      src: `./demos/mobile-first/*`,
      dest: '@demos/mobile-first'
    })

    const menuPath = path.resolve('./demos/saas')
    viteConfig.resolve.alias['@menu'] = menuPath
    // 这里逻辑是兼容saas官网工程的alias写法
    if (!viteConfig.resolve.alias['@opentiny/vue-theme']) {
      viteConfig.resolve.alias['@opentiny/vue-theme'] = '@opentiny/vue-theme-saas'
      viteConfig.resolve.alias['@opentiny/vue-icon'] = '@opentiny/vue-icon-saas'
      viteConfig.resolve.alias['@opentiny/vue-search-box'] = '@opentiny/vue-search-box-saas'
    }
    return viteConfig
  }
}

const modeModifyMap = {
  mobile(viteConfig) {
    viteConfig.build.rollupOptions.input.mobile = path.resolve(__dirname, './mobile.html')
  },
  plus(viteConfig) {
    const demosPath = '../plusdocs'
    const apisPath = '../plusdocs/apis'
    viteConfig.resolve.alias['@menu'] = path.resolve(demosPath)
    viteConfig.resolve.alias['@demos'] = path.resolve(demosPath)
    viteConfig.tinyCustom.copyTarget = [
      {
        src: `${demosPath}/*`,
        dest: '@demos'
      },
      {
        src: `${apisPath}/*`,
        dest: '@demos/apis'
      }
    ]
  }
}

// 针对不同环境针对修改配置
export const modifyViteConfig = (viteConfig, env) => {
  const { VITE_TINY_THEME, VITE_APP_MODE } = env
  const doModeModify = modeModifyMap[VITE_APP_MODE]
  if (doModeModify) {
    doModeModify(viteConfig)
  }
  const doThemeModify = themeModifyMap[VITE_TINY_THEME]
  return doThemeModify ? doThemeModify(viteConfig) : viteConfig
}