import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import fs from 'fs'

const SHARED_SPECIFIERS = ['vue', '@builder/ui', '@inertiajs/vue3']

function builderHotFilePlugin(hotFilePath) {
    return {
        name: 'builder-hot-file',
        configureServer(server) {
            const host =
                server.config.server.host && server.config.server.host !== true
                    ? server.config.server.host
                    : 'localhost'

            const origin = `http://${host}:${server.config.server.port}`

            fs.mkdirSync(path.dirname(hotFilePath), { recursive: true })
            fs.writeFileSync(hotFilePath, origin)

            const cleanup = () => {
                if (fs.existsSync(hotFilePath)) fs.unlinkSync(hotFilePath)
            }

            process.on('exit', cleanup)
            process.on('SIGINT', () => { cleanup(); process.exit() })
            process.on('SIGTERM', () => { cleanup(); process.exit() })
        },
    }
}

function sharedImportsPlugin() {
    const coreHotFile = path.resolve(__dirname, '../core/public/hot')

    const getCoreUrl = () =>
        fs.existsSync(coreHotFile)
            ? fs.readFileSync(coreHotFile, 'utf-8').trim()
            : 'http://localhost:5173'

    const SHARED_MAP = {
        'vue': '/resources/js/vendor/vue.ts',
        '@builder/ui': '/resources/js/ui/index.ts',
        '@inertiajs/vue3': '/resources/js/vendor/inertia.ts',
    }

    const PREFIX = '\0shared:'

    return {
        name: 'shared-imports',
        enforce: 'pre',
        resolveId(id) {
            if (id in SHARED_MAP) {
                return PREFIX + id
            }
        },
        load(id) {
            if (id.startsWith(PREFIX)) {
                const specifier = id.slice(PREFIX.length)
                const url = getCoreUrl() + SHARED_MAP[specifier]
                return `export * from '${url}'`
            }
        },
    }
}

export default defineConfig(({ command }) => {
    const isDev = command === 'serve'
    const hotFile = path.resolve(__dirname, 'public/hot')

    return {
        root: __dirname,
        plugins: [
            vue(),
            isDev ? builderHotFilePlugin(hotFile) : undefined,
            isDev ? sharedImportsPlugin() : undefined,
        ].filter(Boolean),

        publicDir: false,

        base: isDev ? '/' : '/vendor/builder/seo/',

        build: {
            manifest: true,
            outDir: 'public',
            emptyOutDir: true,
            rollupOptions: {
                input: {
                    index: path.resolve(__dirname, 'resources/js/index.ts'),
                },
                external: SHARED_SPECIFIERS,
                preserveEntrySignatures: 'exports-only',
                output: {
                    entryFileNames: 'assets/[name]-[hash].js',
                    chunkFileNames: 'assets/[name]-[hash].js',
                },
            },
        },

        optimizeDeps: {
            exclude: SHARED_SPECIFIERS,
        },

        server: {
            port: 5177,
            strictPort: true,
            cors: true,
        },
    }
})
