// @ts-ignore
import react from '@vitejs/plugin-react'
import { compression } from 'vite-plugin-compression2'
import cssInjectedByJs from 'vite-plugin-css-injected-by-js'
// @ts-ignore
import { defineConfig, loadEnv, type Plugin } from 'vite'
import { resolve } from 'path'
import { constants as zlibConstants } from 'zlib'
import { request as httpRequest } from 'http'
import tinyLR from 'tiny-lr'

const isDev = (mode: string): boolean => mode !== 'production'

const LIVERELOAD_PORT = 35729
const LIVERELOAD_SNIPPET = `;(function(){var scriptElement=document.createElement('script');scriptElement.src='http://localhost:${LIVERELOAD_PORT}/livereload.js?snipver=1';document.head.appendChild(scriptElement)})()`

const liveReloadPlugin = (): Plugin => {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const liveReloadServer = tinyLR()
    let started = false

    let lastReload = 0
    const triggerReload = (): void => {
        const now = Date.now()
        if (now - lastReload < 3000) return
        lastReload = now
        // eslint-disable-next-line @typescript-eslint/no-require-imports
        const request = httpRequest
        const body = JSON.stringify({ files: ['*'] })
        const requestObject = request({
            hostname: 'localhost',
            port: LIVERELOAD_PORT,
            path: '/changed',
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
        })
        requestObject.on('error', (error) => {})
        requestObject.write(body)
        requestObject.end()
    }

    return {
        name: 'live-reload',
        apply: 'build',
        buildStart() {
            if (started) return
            started = true
            liveReloadServer.server.on('error', (error: NodeJS.ErrnoException) => {
                if (error.code !== 'EADDRINUSE') console.error('[Live Reload]', error)
            })
            liveReloadServer.listen(LIVERELOAD_PORT, () => {
                console.log(`[Live Reload] enabled on port ${LIVERELOAD_PORT}`)
            })
        },
        renderChunk(code: string, chunk: { isEntry: any }) {
            if (chunk.isEntry) {
                return { code: code + LIVERELOAD_SNIPPET }
            }
            return null
        },
        closeBundle() {
            triggerReload()
        },
    }
}

// @ts-ignore
export default defineConfig(({ mode }) => {
    const environmentConfig = loadEnv(mode, process.cwd(), '')
    const shouldGenerateSourceMap =
        process.env.GENERATE_SOURCEMAP === 'true' || environmentConfig.GENERATE_SOURCEMAP === 'true'

    return {
        plugins: [
            react(),
            cssInjectedByJs(),
            isDev(mode) && liveReloadPlugin(),
            !isDev(mode) &&
                compression({
                    // @ts-ignore
                    algorithm: 'brotliCompress',
                    filename: '[path][base].br',
                    compressionOptions: { params: { [zlibConstants.BROTLI_PARAM_QUALITY]: 11 } },
                    threshold: 10240,
                    deleteOriginalAssets: false,
                }),
        ],
        resolve: {
            alias: {
                '@': resolve(__dirname, 'src'),
            },
        },
        define: {
            'process.env.NODE_ENV': JSON.stringify(isDev(mode) ? 'development' : 'production'),
            'process.env.APP_VERSION': JSON.stringify(environmentConfig.APP_VERSION),
            'process.env.API_KEY': JSON.stringify(environmentConfig.API_KEY),
            'process.env.APP_ENV': JSON.stringify(environmentConfig.APP_ENV),
            'process.env.LOGGLY_KEY': JSON.stringify(environmentConfig.LOGGLY_KEY),
            'process.env.REQUIRED_API_VERSION': JSON.stringify(environmentConfig.REQUIRED_API_VERSION),
            'process.env.MUI_X_LICENSE_KEY': JSON.stringify(environmentConfig.MUI_X_LICENSE_KEY),
            'process.env.POSTHOG_API_KEY': JSON.stringify(environmentConfig.POSTHOG_API_KEY),
            'process.env.POSTHOG_HOST': JSON.stringify(environmentConfig.POSTHOG_HOST),
            'process.env.FEEDBACK_WEBHOOK_URL': JSON.stringify(environmentConfig.FEEDBACK_WEBHOOK_URL),
            'process.env.MUI_X_TELEMETRY_DISABLED': JSON.stringify(environmentConfig.MUI_X_TELEMETRY_DISABLED),
        },
        build: {
            outDir: resolve(__dirname, '../dist/admin-portal'),
            emptyOutDir: true,
            sourcemap: shouldGenerateSourceMap ? true : false,
            minify: !isDev(mode),
            assetsInlineLimit: 1024 * 50,
            rollupOptions: {
                input: { main: resolve(__dirname, 'src/index.tsx') },
                output: {
                    format: 'iife',
                    entryFileNames: '[name].bundle.js',
                    assetFileNames: (assetInfo: { name: string }) => {
                        const assetName = assetInfo.name ?? ''
                        if (/\.(woff2?|ttf|eot)(\?.*)?$/.test(assetName)) return 'fonts/[name][extname]'
                        return 'assets/[name][extname]'
                    },
                },
            },
        },
    }
})
