import path from 'path';
import fs from 'fs';
import os from 'os';
import crypto from 'crypto';
import { fileURLToPath } from 'url';
import { ensureBootstrap } from './engines/client-bootstrap.js';
import { ASCII_ART, printASCIILogo, printBootSuccessMessage, runInstallBootSequence } from './utils/ascii-art.js';
import { resolveWorkspaceContext } from './engines/workspace-resolver.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageRoot = path.join(__dirname, '..');
// Get version from package.json
let version = '4.4.0';
try {
    const pkgPath = path.join(packageRoot, 'package.json');
    const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
    version = pkg.version || version;
}
catch {
    // fallback to default version
}
function appendInstallLog(message) {
    try {
        const logDir = path.join(os.homedir(), '.nexus-prime');
        if (!fs.existsSync(logDir)) {
            fs.mkdirSync(logDir, { recursive: true });
        }
        const logPath = path.join(logDir, 'install.log');
        const timestamp = new Date().toISOString();
        fs.appendFileSync(logPath, `[${timestamp}] ${message}\n`);
    }
    catch {
        // Best-effort logging — never fail the install for a log write
    }
}
function shouldShowInstallBanner() {
    return process.env.CI !== 'true' && !process.env.NEXUS_SILENT_INSTALL;
}
function shouldAnimateInstall() {
    if (!shouldShowInstallBanner())
        return false;
    return Boolean(process.stdout.isTTY && process.stderr.isTTY);
}
function startInstallSpinner() {
    if (!shouldAnimateInstall())
        return null;
    let frame = 0;
    const frames = Array.isArray(ASCII_ART.sciFiLoaderFrames) && ASCII_ART.sciFiLoaderFrames.length > 0
        ? ASCII_ART.sciFiLoaderFrames
        : [ASCII_ART.sciFiLoader(0)];
    const frameRate = Math.max(60, Number(ASCII_ART.sciFiLoaderFrameRateMs || 90));
    const render = () => {
        const glyph = frames[frame % frames.length];
        process.stderr.write(`\r\x1b[35m${glyph}\x1b[0m`);
        frame += 1;
    };
    render();
    const handle = setInterval(render, frameRate);
    return {
        stop(message = '') {
            clearInterval(handle);
            process.stderr.write('\r\x1b[2K');
            if (message) {
                process.stderr.write(`\r\x1b[32m${message}\x1b[0m\n`);
            }
        },
    };
}
async function runWithRetry(maxRetries = 3, delayMs = 1000) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            if (process.env.NEXUS_BOOTSTRAP_DISABLE === '1') {
                appendInstallLog('Bootstrap disabled via NEXUS_BOOTSTRAP_DISABLE=1');
                process.exit(0);
            }
            // Show ASCII art during installation (non-silent mode)
            if (shouldShowInstallBanner()) {
                console.log('');
                if (shouldAnimateInstall()) {
                    await runInstallBootSequence(version);
                }
                else {
                    printASCIILogo(version);
                }
            }
            const spinner = startInstallSpinner();
            try {
                const workspace = resolveWorkspaceContext({ workspaceRoot: process.cwd() });
                ensureBootstrap({
                    packageRoot,
                    workspaceRoot: workspace.workspaceRoot,
                    phase: 'install',
                    silent: true,
                });
                spinner?.stop('✔ bootstrap complete');
            }
            catch (error) {
                spinner?.stop();
                throw error;
            }
            // Show success message
            if (shouldShowInstallBanner()) {
                printBootSuccessMessage(version);
            }
            // Generate anonymous install UUID for telemetry (opt-in only, no data sent by default)
            let installId = '';
            try {
                const installIdPath = path.join(os.homedir(), '.nexus-prime', 'install-id');
                if (!fs.existsSync(installIdPath)) {
                    installId = crypto.randomUUID();
                    fs.writeFileSync(installIdPath, installId, 'utf8');
                    appendInstallLog(`Install UUID generated: ${installId.slice(0, 8)}...`);
                }
                else {
                    installId = fs.readFileSync(installIdPath, 'utf8').trim();
                }
            }
            catch { /* non-fatal */ }
            // Register install with Supabase (fire-and-forget)
            try {
                const { registerInstall } = await import('./engines/install-registry.js');
                registerInstall(installId || 'unknown', version);
            }
            catch { /* non-fatal — install tracking is best-effort */ }
            // Show license request prompt
            if (shouldShowInstallBanner()) {
                try {
                    const licenseKeyPath = path.join(os.homedir(), '.nexus-prime', 'license.key');
                    if (!fs.existsSync(licenseKeyPath)) {
                        console.log('');
                        console.log('\u2554' + '\u2550'.repeat(50) + '\u2557');
                        console.log('\u2551  3-day no-license grace is active.             \u2551');
                        console.log('\u2551  Request a license before day 4:               \u2551');
                        console.log('\u2551  \u2192 https://nexus-prime.cfd/account                 \u2551');
                        console.log('\u2551  \u2192 adarsh@nexus-prime.cfd                         \u2551');
                        console.log('\u2551                                                  \u2551');
                        console.log('\u2551  Team shares licenses within 24 hours.         \u2551');
                        console.log('\u2551  nexus-prime license activate <your-token>       \u2551');
                        console.log('\u255A' + '\u2550'.repeat(50) + '\u255D');
                    }
                }
                catch { /* non-fatal */ }
            }
            appendInstallLog(`Bootstrap complete (workspace: ${resolveWorkspaceContext({ workspaceRoot: process.cwd() }).workspaceRoot})`);
            return;
        }
        catch (error) {
            process.stderr.write('\r\x1b[2K');
            const code = error instanceof Error && 'code' in error ? String(error.code) : '';
            const isRetryable = code === 'EBUSY' || code === 'EACCES';
            const message = error instanceof Error ? error.message : String(error);
            const stack = error instanceof Error ? error.stack : undefined;
            if (isRetryable && attempt < maxRetries) {
                console.warn(`[nexus-prime] Bootstrap encountered ${code}, retrying in ${delayMs}ms (attempt ${attempt}/${maxRetries})...`);
                appendInstallLog(`Retry ${attempt}/${maxRetries}: ${code} — ${message}`);
                await new Promise(resolve => setTimeout(resolve, delayMs));
            }
            else {
                if (isRetryable) {
                    console.error(`[nexus-prime] postinstall bootstrap failed after ${maxRetries} attempts: ${message}`);
                }
                else {
                    console.error(`[nexus-prime] postinstall bootstrap skipped: ${message}`);
                }
                appendInstallLog(`Bootstrap failed: ${message}${stack ? '\n' + stack : ''}`);
                return;
            }
        }
    }
}
runWithRetry().catch(err => {
    console.error('[PostInstall] Bootstrap retry failed:', err?.message ?? err);
    // non-fatal, process may already be exiting
});
