import { URL, fileURLToPath } from 'node:url'
import * as path from 'node:path'
import { defineConfig, loadEnv } from 'vite'
import type { ConfigEnv, UserConfig, UserConfigExport } from 'vite'
import dayjs from 'dayjs'
import { ViteEjsPlugin } from 'vite-plugin-ejs'
import BuildMessage from '@neosjs/unplugin-build-message/vite'
<%_ for (const { importer } of plugins) { _%>
<%- importer %>
<%_ } _%>
import pkg from './package.json'

const buildTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
const { name, version } = pkg
const BANNER = `
/*!
* ${name}
* Version: ${version}
* ReleaseTime: ${buildTime}
* Copyright ${dayjs().format('YYYY')}
*/
`

const wrapperEnv = (envConf: Recordable): ViteEnv => {
  const ret: any = {}
  for (const envName of Object.keys(envConf)) {
    let realName = envConf[envName].replace(/\\n/g, '\n')
    realName = realName === 'true' ? true : realName === 'false' ? false : realName
    if (envName === 'VITE_PORT') realName = Number(realName)
    ret[envName] = realName
    if (typeof realName === 'string') {
      process.env[envName] = realName
    } else if (typeof realName === 'object') {
      process.env[envName] = JSON.stringify(realName)
    }
  }
  return ret
}

// https://vitejs.dev/config/
export default ({ mode }: ConfigEnv): UserConfigExport => {
  const ENV = Object.assign(loadEnv(mode, process.cwd()))
  const viteEnv = wrapperEnv(ENV)
  const {
    VITE_TITLE,
    VITE_PORT,
    VITE_BASE_PATH,
    VITE_DROP_CONSOLE,
    VITE_SOURCEMAP,
    VITE_OUT_DIR,
    <% if (used.usePWA) {%>VITE_PWA_CLAIMS,<% } %>
    <% if (used.isH5) {%>VITE_ENV,<% } %>
    VITE_ASSETS_DIR
  } = viteEnv
  const __APP_INFO__ = {
    title: VITE_TITLE || name,
    version,
    buildTime
  }
  return defineConfig({
    base: `${VITE_BASE_PATH}`,
    plugins: [
    <%_ for (const { initializer } of plugins) { _%>
      <%- initializer _%>,
    <%_ } _%>
      BuildMessage(),
      ViteEjsPlugin((viteConfig: UserConfig) => {
        return {
          root: viteConfig.base,
          appType: viteConfig.appType,
          title: VITE_TITLE || name,
          buildTime,
          version
        }
      })
    ],
    server: {
      host: true,
      open: true,
      port: VITE_PORT,
    },
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
        '#': fileURLToPath(new URL('./types', import.meta.url))
      }
    },
    build: {
      outDir: VITE_OUT_DIR,
      assetsDir: VITE_ASSETS_DIR,
      cssCodeSplit: true,
      sourcemap: VITE_SOURCEMAP,
      chunkSizeWarningLimit: 2 * 1024 * 1024, // 2MB
      rollupOptions: {
        output: {
          banner:BANNER,
          chunkFileNames: `${VITE_ASSETS_DIR}/js/[hash].js`,
          entryFileNames: `${VITE_ASSETS_DIR}/js/[hash].js`,
          assetFileNames: (chunkInfo: any) => {
            const { name } = chunkInfo
            const fileExt = name.split('.')
            return `${VITE_ASSETS_DIR}/${fileExt[1] === 'css' ? 'css' : 'imgs'}/[hash].${fileExt[1]}`
          },
          manualChunks: {
            vue: ['vue'<% if (used.useRouter) {%>, 'vue-router'<% } %>],
            <% if (used.usePinia) {%>pinia: ['pinia', 'pinia-plugin-persistedstate'],<% } %>
            <% if (used.useVueuse) {%>vueuse: ['@vueuse/core'],<% } %>
            dayjs: ['dayjs', 'dayjs/plugin/utc', 'dayjs/plugin/timezone']
          }
        }
      },
      minify: 'esbuild'
    },
    esbuild: {
      pure: VITE_DROP_CONSOLE ? ['console.log'] : [], //  打包时移除 console.log
      drop: VITE_DROP_CONSOLE ? ['debugger'] : [], // 打包时移除 debugger
      legalComments: 'none' // 打包时移除所有注释
    },
    optimizeDeps: {
      include: [
        'vue',
        'lodash-es',
        <% if (used.useRouter) {%>'vue-router',<% } %>
        <% if (used.usePinia) {%>'pinia',<% } %>
        <% if (used.useVueuse) {%>'@vueuse/core'<% } %>
      ]
    },
    define: {
      __APP_INFO__: JSON.stringify(__APP_INFO__),
      __APP_VERSION__: JSON.stringify(version)
    }
  })
}
