import path from 'node:path'
import fs from 'node:fs'
import colors from 'picocolors'
import type { Plugin, ResolvedConfig } from 'vite'
import { getEnvConfig, getRootPath } from '../../utils'
import { getConfigFileName } from '../../getConfigFileName'
import { GLOB_CONFIG_FILE_NAME } from '../../constant'
import pkg from '../../../package.json'

export function configBuildPlugin(): Plugin {
    let outputPath: string
    let config: ResolvedConfig

    return {
        name: 'vite:app:config',
        apply: 'build',
        enforce: 'post',
        configResolved(resolvedConfig: ResolvedConfig) {
            config = resolvedConfig
            outputPath = path.isAbsolute(config.build.outDir)
                ? config.build.outDir
                : path.join(config.root, config.build.outDir)
        },
        async closeBundle() {
            const config = getEnvConfig()
            const configName = getConfigFileName(config)
            const windowConf = `window.${configName}`

            // Ensure that the variable will not be modified
            let configStr = `${windowConf}=${JSON.stringify(config)};`
            configStr += `
                Object.freeze(${windowConf});
                Object.defineProperty(window, "${configName}", {
                    configurable: false,
                    writable: false,
                });
            `.replace(/\s/g, '')

            fs.writeFileSync(getRootPath(`${outputPath}/${GLOB_CONFIG_FILE_NAME}`), configStr)

            console.log(`${colors.cyan(`✨ [${pkg.name}]`)} configuration file is build successfully:`)
            console.log(`${colors.gray(`${outputPath}/${colors.green(GLOB_CONFIG_FILE_NAME)}`)}\n`)
        },
    } as Plugin
}
