// cPanel Node.js Application Startup File
// This file is the entry point for cPanel's "Setup Node.js App" feature
const path = require('path');
const fs = require('fs');
const http = require('http');

// ── Error logging setup ──────────────────────────────────
const logFile = path.join(__dirname, 'app-error.log');
function logError(msg) {
    const timestamp = new Date().toISOString();
    const line = `[${timestamp}] ${msg}\n`;
    try { fs.appendFileSync(logFile, line); } catch (e) { /* ignore */ }
    console.error(line);
}

process.on('uncaughtException', (err) => {
    logError(`UNCAUGHT EXCEPTION: ${err.stack || err.message || err}`);
    process.exit(1);
});

process.on('unhandledRejection', (reason) => {
    logError(`UNHANDLED REJECTION: ${reason}`);
});

// ── Load .env.local into process.env ─────────────────────
const envFiles = ['.env.local', '.env.production', '.env'];
for (const envFile of envFiles) {
    const envPath = path.join(__dirname, envFile);
    if (fs.existsSync(envPath)) {
        const lines = fs.readFileSync(envPath, 'utf-8').split('\n');
        for (const line of lines) {
            const trimmed = line.trim();
            if (!trimmed || trimmed.startsWith('#')) continue;
            const eqIndex = trimmed.indexOf('=');
            if (eqIndex === -1) continue;
            const key = trimmed.slice(0, eqIndex).trim();
            const value = trimmed.slice(eqIndex + 1).trim();
            if (!process.env[key]) {
                process.env[key] = value;
            }
        }
        logError(`Loaded env file: ${envFile}`);
    }
}

// ── Set production environment ───────────────────────────
process.env.NODE_ENV = 'production';
process.env.PORT = process.env.PORT || '3000';
process.env.HOSTNAME = '0.0.0.0';

// ── Read BUILD_ID for health checks ─────────────────────
let buildId = 'unknown';
try {
    buildId = fs.readFileSync(path.join(__dirname, '.next', 'BUILD_ID'), 'utf-8').trim();
} catch (e) { /* ignore */ }

logError(`Starting server (Node ${process.version}, PORT=${process.env.PORT}, BUILD=${buildId})`);

// ── Intercept HTTP server to add health/debug endpoints ──
const origCreateServer = http.createServer;
http.createServer = function (handler) {
    const server = origCreateServer.call(this, (req, res) => {
        // /__health - quick health check
        if (req.url === '/__health' || req.url === '/__health/') {
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({
                status: 'ok',
                buildId,
                nodeVersion: process.version,
                uptime: process.uptime(),
                timestamp: new Date().toISOString(),
                cwd: process.cwd(),
                dirname: __dirname,
                envFiles: envFiles.filter(f => fs.existsSync(path.join(__dirname, f))),
                hasSupabaseUrl: !!process.env.NEXT_PUBLIC_SUPABASE_URL,
                hasSupabaseKey: !!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
            }));
            return;
        }

        // /__routes - check what routes are registered
        if (req.url === '/__routes' || req.url === '/__routes/') {
            let routesManifest = null;
            try {
                routesManifest = JSON.parse(fs.readFileSync(
                    path.join(__dirname, '.next', 'routes-manifest.json'), 'utf-8'
                ));
            } catch (e) { /* ignore */ }

            const dynamicRoutes = routesManifest?.dynamicRoutes?.map(r => ({
                page: r.page,
                regex: r.regex,
            })) || [];

            const slugPagePath = path.join(__dirname, '.next', 'server', 'app', '(public)', '[slug]', 'page.js');
            const debugPagePath = path.join(__dirname, '.next', 'server', 'app', 'api', 'debug-page', 'route.js');

            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({
                dynamicRouteCount: dynamicRoutes.length,
                dynamicRoutes,
                slugPageExists: fs.existsSync(slugPagePath),
                debugPageExists: fs.existsSync(debugPagePath),
                serverAppDirs: fs.existsSync(path.join(__dirname, '.next', 'server', 'app'))
                    ? fs.readdirSync(path.join(__dirname, '.next', 'server', 'app'))
                    : 'NOT FOUND',
            }, null, 2));
            return;
        }

        // /__config - read required-server-files.json to check path config
        if (req.url === '/__config' || req.url === '/__config/') {
            let rsf = null;
            let raw = '';
            try {
                raw = fs.readFileSync(path.join(__dirname, '.next', 'required-server-files.json'), 'utf-8');
                rsf = JSON.parse(raw);
            } catch (e) { /* ignore */ }

            // Check for Windows paths
            const windowsPathsFound = (raw.match(/[A-Z]:\\\\[^"]+/g) || []).slice(0, 10);

            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.end(JSON.stringify({
                appDir: rsf?.appDir || 'NOT_SET',
                relativeAppDir: rsf?.relativeAppDir || 'NOT_SET',
                outputFileTracingRoot: rsf?.config?.outputFileTracingRoot || 'NOT_SET',
                distDir: rsf?.config?.distDir || 'NOT_SET',
                windowsPathsFound: windowsPathsFound.length > 0 ? windowsPathsFound : 'NONE',
                redirectCount: rsf?.config?.redirects?.length || 0,
                redirectSources: (rsf?.config?.redirects || []).map(r => r.source),
            }, null, 2));
            return;
        }

        // Pass everything else to Next.js
        handler(req, res);
    });
    return server;
};

// ── Start the Next.js standalone server ──────────────────
try {
    require('./server.js');
} catch (err) {
    logError(`FATAL: Failed to require server.js: ${err.stack || err.message || err}`);
    process.exit(1);
}
