import react from '@vitejs/plugin-react-swc';
import { existsSync, readFileSync } from 'node:fs';
import path from 'node:path';
import { defineConfig, loadEnv } from 'vite';
import { createHtmlPlugin } from 'vite-plugin-html';
import tsconfigPaths from 'vite-tsconfig-paths';

import { generateCertificates } from './scripts/generate-ssl.ts';
import { getGitHash } from './scripts/lib.ts';

const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
const readme = readFileSync('README.md', 'utf8');

export default defineConfig(({ mode }) => {
    const viteEnv = loadEnv(mode, process.cwd(), '');
    const vitePort = viteEnv.VITE_PORT ? Number.parseInt(viteEnv.VITE_PORT, 10) : 8000;
    const viteHost = viteEnv.VITE_HOST || '0.0.0.0';
    const useHttps = viteEnv.VITE_USE_HTTPS === 'true';

    const sslKeyPath = viteEnv.VITE_SSL_KEY_PATH || 'ssl/server.key';
    const sslCertPath = viteEnv.VITE_SSL_CERT_PATH || 'ssl/server.crt';

    if (useHttps && (!existsSync(sslKeyPath) || !existsSync(sslCertPath))) {
        console.log('SSL certificates not found. Attempting to generate them...');

        try {
            generateCertificates();
        } catch {
            console.warn('Failed to generate SSL certificates. Falling back to HTTP.');
            process.env.VITE_USE_HTTPS = 'false';
        }
    }

    const serverConfig = {
        host: viteHost,
        port: vitePort,
        proxy: {
            '/api/v1': {
                changeOrigin: true,
                secure: false,
                target: `${useHttps ? 'https' : 'http'}://${viteEnv.VITE_API_URL}`,
            },
            '/api/v1/graphql': {
                changeOrigin: true,
                secure: false,
                target: `${useHttps ? 'wss' : 'ws'}://${viteEnv.VITE_API_URL}`,
                wss: `${useHttps}`,
            },
        },
        ...(useHttps && {
            https: {
                cert: readFileSync(sslCertPath),
                key: readFileSync(sslKeyPath),
            },
        }),
    };

    return {
        build: {
            chunkSizeWarningLimit: 1000,
            minify: 'terser',
            rollupOptions: {
                output: {
                    manualChunks: (id: string) => {
                        if (!id.includes('node_modules')) {
                            return;
                        }
                        if (/[\\/]@apollo[\\/]client|[\\/]graphql[\\/]|[\\/]graphql-ws[\\/]/.test(id)) {
                            return 'apollo-client';
                        }
                        if (/[\\/](react-markdown|rehype-highlight|rehype-raw|rehype-slug|remark-gfm)[\\/]/.test(id)) {
                            return 'markdown';
                        }
                        if (/[\\/]@radix-ui[\\/]/.test(id)) {
                            return 'radix-ui';
                        }
                        if (/[\\/]@xterm[\\/]/.test(id)) {
                            return 'terminal';
                        }
                        if (/[\\/](react|react-dom|react-router-dom)[\\/]/.test(id)) {
                            return 'react-vendor';
                        }
                    },
                },
            },
            sourcemap: false,
            terserOptions: {
                compress: {
                    drop_console: mode === 'production',
                    drop_debugger: mode === 'production',
                },
            },
        },
        define: {
            APP_DEV_CWD: JSON.stringify(process.cwd()),
            APP_NAME: JSON.stringify(pkg.name),
            APP_VERSION: JSON.stringify(pkg.version),
            dependencies: JSON.stringify(pkg.dependencies),
            devDependencies: JSON.stringify(pkg.devDependencies),
            GIT_COMMIT_SHA: JSON.stringify(getGitHash()),
            pkg: JSON.stringify(pkg),
            README: JSON.stringify(readme),
        },
        plugins: [
            tsconfigPaths(),
            react(),
            createHtmlPlugin({
                inject: {
                    data: {
                        title: viteEnv.VITE_APP_NAME,
                    },
                },
                template: 'index.html',
            }),
        ],
        resolve: {
            alias: {
                '@': path.resolve(__dirname, './src'),
            },
        },
        server: serverConfig,
    };
});
