import process from 'node:process'
import { resolve } from 'node:path'
import type { ConfigEnv, UserConfig } from 'vite'
import dayjs from 'dayjs'
import { loadEnv } from 'vite'
import pkg from './package.json'
import { generateModifyVars } from './build/generate/generateModifyVars'
import { createProxy } from './build/vite/proxy'
import { wrapperEnv } from './build/utils'
import { createVitePlugins } from './build/vite/plugin'

function pathResolve(dir: string) {
    return resolve(process.cwd(), '.', dir)
}

const { dependencies, devDependencies, name, version } = pkg
const __APP_INFO__ = {
    pkg: { dependencies, devDependencies, name, version },
    lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
}

export default ({ command, mode }: ConfigEnv): UserConfig => {
    const root = process.cwd()

    const env = loadEnv(mode, root)

    // The boolean type read by loadEnv is a string. This function can be converted to boolean type
    const viteEnv = wrapperEnv(env)

    const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv

    const isBuild = command === 'build'

    return {
        base: VITE_PUBLIC_PATH,
        root,
        resolve: {
            alias: [
                {
                    find: 'vue-i18n',
                    replacement: 'vue-i18n/dist/vue-i18n.cjs.js',
                },
                // /@/xxxx => src/xxxx
                {
                    find: /\/?@\//,
                    replacement: `${pathResolve('src')}/`,
                },
                // /#/xxxx => types/xxxx
                {
                    find: /\/#\//,
                    replacement: `${pathResolve('types')}/`,
                },
            ],
        },
        server: {
            https: false,
            // Listening on all local IPs
            host: true,
            port: VITE_PORT,
            // Load proxy configuration from .env
            proxy: createProxy(VITE_PROXY),
        },
        build: {
            target: 'es2015',
            cssTarget: 'chrome80',
            // Turning off brotliSize display can slightly reduce packaging time
            reportCompressedSize: false,
            chunkSizeWarningLimit: 2000,
        },
        define: {
            // setting vue-i18-next
            // Suppress warning
            __INTLIFY_PROD_DEVTOOLS__: false,
            __APP_INFO__: JSON.stringify(__APP_INFO__),
            __APP__: {
                name: pkg.name,
                version: pkg.version,
                description: pkg.description,
                author: pkg.author,
                lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
            },

            // FIX: https://github.com/vbenjs/vite-plugin-theme/issues/27
            __COLOR_PLUGIN_OUTPUT_FILE_NAME__: undefined,
            __PROD__: true,
            __COLOR_PLUGIN_OPTIONS__: {},
        },

        css: {
            preprocessorOptions: {
                less: {
                    modifyVars: generateModifyVars(),
                    javascriptEnabled: true,
                },
            },
        },

        // The vite plugin used by the project. The quantity is large, so it is separately extracted and managed
        plugins: createVitePlugins(viteEnv, isBuild),

        optimizeDeps: {
            // @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly
            include: ['@iconify/iconify', 'ant-design-vue/es/locale/zh_CN', 'ant-design-vue/es/locale/en_US'],
        },
    }
}
