import { vitePluginForArco } from '@arco-plugins/vite-vue';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { resolve } from 'path';
import visualizer from 'rollup-plugin-visualizer';
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
import Components from 'unplugin-vue-components/vite';
import { defineConfig, type PluginOption } from 'vite';
import compressPlugin from 'vite-plugin-compression';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import svgLoader from 'vite-svg-loader';

const manualChunkGroups: Record<string, string[]> = {
  arco: ['@arco-design/web-vue'],
  chart: ['echarts', 'vue-echarts'],
  vue: ['vue', 'vue-router', 'pinia', '@vueuse/core', 'vue-i18n'],
};

function manualChunks(id: string) {
  if (!id.includes('node_modules')) return;
  for (const [chunkName, packages] of Object.entries(manualChunkGroups)) {
    for (const pkg of packages) {
      if (id.includes(`node_modules/${pkg}`)) {
        return chunkName;
      }
    }
  }
}

export default defineConfig(({ command, mode }) => {
  const isDev = command === 'serve';
  const isReport = mode === 'report';

  const plugins: PluginOption[] = [
    vue(),
    vueJsx(),
    svgLoader({ svgoConfig: {} }),
    vitePluginForArco({}),
  ];

  if (!isDev) {
    plugins.push(
      Components({
        dirs: [],
        deep: false,
        resolvers: [ArcoResolver()],
      }),
      compressPlugin({ ext: '.gz' }),
      ViteImageOptimizer({
        png: { quality: 80 },
        jpeg: { quality: 80 },
        jpg: { quality: 80 },
        webp: { quality: 80 },
      }),
    );

    if (isReport) {
      plugins.push(
        visualizer({
          filename: './node_modules/.cache/visualizer/stats.html',
          open: true,
          gzipSize: true,
          brotliSize: true,
        }),
      );
    }
  }

  return {
    plugins,
    resolve: {
      alias: [
        { find: '@', replacement: resolve(__dirname, '../src') },
        { find: 'assets', replacement: resolve(__dirname, '../src/assets') },
        {
          find: 'vue-i18n',
          replacement: 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js',
        },
        {
          find: 'vue',
          replacement: 'vue/dist/vue.esm-bundler.js',
        },
      ],
      extensions: ['.ts', '.js'],
    },
    css: {
      preprocessorOptions: {
        less: {
          modifyVars: {
            hack: `true; @import (reference) "${resolve(
              'src/assets/style/breakpoint.less',
            )}";`,
          },
          javascriptEnabled: true,
        },
      },
    },
    server: isDev
      ? {
          open: true,
          fs: { strict: true },
        }
      : undefined,
    build: isDev
      ? undefined
      : {
          rollupOptions: {
            output: { manualChunks },
          },
          chunkSizeWarningLimit: 2000,
        },
  };
});
