"use strict";
/**
 * LoggingUI — Logging-only implementation for CI mode.
 * No prompts, no TUI, no interactivity. Just console output.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoggingUI = void 0;
const wizard_ui_1 = require("./wizard-ui");
class LoggingUI {
    intro(message) {
        console.log(`┌  ${message}`);
    }
    outro(message) {
        console.log(`└  ${message}`);
    }
    cancel(message, options) {
        // Cancel implies failure/abort — direct to stderr so callers can detect it
        console.error(`■  ${message}`);
        if (options?.docsUrl) {
            console.error(`│  Manual setup guide: ${options.docsUrl}`);
        }
        // No TUI in logging mode — stderr write completes synchronously,
        // resolve immediately so wizardAbort isn't held up.
        return Promise.resolve();
    }
    setOutroData(data) {
        // No TUI to render — emit the message inline so CI logs capture it.
        if (data.message)
            console.error(`■  ${data.message}`);
    }
    log = {
        info(message) {
            console.log(`│  ${message}`);
        },
        warn(message) {
            // Route warnings to stderr so pipe consumers can separate signal from errors
            console.error(`▲  ${message}`);
        },
        error(message) {
            // Route errors to stderr — stdout should remain clean for structured
            // output (e.g. --json / agent mode) and for shell piping.
            console.error(`✖  ${message}`);
        },
        success(message) {
            console.log(`✔  ${message}`);
        },
        step(message) {
            console.log(`◇  ${message}`);
        },
    };
    note(message) {
        console.log(`│  ${message}`);
    }
    spinner() {
        let activeMessage;
        return {
            start(message) {
                if (message) {
                    activeMessage = message;
                    // Write without newline so stop() can overwrite in-place
                    process.stdout.write(`◌  ${message}`);
                }
            },
            stop(message) {
                if (activeMessage !== undefined) {
                    // Overwrite the current spinner line: carriage-return → solid dot → newline
                    process.stdout.write(`\r●  ${message ?? activeMessage}\n`);
                    activeMessage = undefined;
                }
                else if (message) {
                    console.log(`●  ${message}`);
                }
            },
            message(msg) {
                if (!msg)
                    return;
                if (activeMessage !== undefined) {
                    // Overwrite the current spinner line with the new task
                    process.stdout.write(`\r◌  ${msg}`);
                }
                else {
                    process.stdout.write(`◌  ${msg}`);
                }
                activeMessage = msg;
            },
        };
    }
    pushStatus(message) {
        console.log(`◇  ${message}`);
    }
    seedPostAgentSteps(steps) {
        if (steps.length === 0)
            return;
        console.log(`│  Finalizing in Amplitude (${steps.length} step${steps.length === 1 ? '' : 's'})…`);
    }
    setPostAgentStep(id, patch) {
        if (patch.status === 'in_progress') {
            console.log(`◌  ${id}…`);
        }
        else if (patch.status === 'completed') {
            console.log(`●  ${id} done`);
        }
        else if (patch.status === 'skipped') {
            const reason = patch.reason ? ` — ${patch.reason}` : '';
            console.log(`⊘  ${id} skipped${reason}`);
        }
    }
    heartbeat(data) {
        // Only paint when there's something to summarize — a beat with no
        // recent statuses is a liveness signal for orchestrators (AgentUI
        // surfaces it on NDJSON), not user-facing log noise.
        if (data.statuses.length === 0)
            return;
        const seconds = Math.round(data.elapsedMs / 1000);
        // End the current in-progress spinner line before printing
        process.stdout.write('\n');
        console.log(`│  Still working — ${seconds}s elapsed`);
        for (const s of data.statuses) {
            console.log(`│  ${s}`);
        }
    }
    setDetectedFramework(label) {
        console.log(`✔  Framework: ${label}`);
    }
    onEnterScreen(_screen, _fn) {
        // No screen transitions in CI
    }
    setLoginUrl(url) {
        if (url) {
            console.log(`│  If the browser didn't open automatically, use this link:`);
            console.log(`│  ${url}`);
        }
    }
    showServiceStatus(data) {
        // Service status is a warning — goes to stderr
        console.error(`▲  The setup agent is temporarily unavailable.`);
        console.error(`│  Status: ${data.description}`);
        console.error(`│  Status page: ${data.statusPageUrl}`);
        console.error(`│  The wizard may not work reliably while services are affected.`);
    }
    setRetryState(state) {
        if (!state)
            return;
        const status = state.errorStatus ? ` (HTTP ${state.errorStatus})` : '';
        const eta = Math.max(0, Math.round((state.nextRetryAtMs - Date.now()) / 1000));
        // Retry notices are warning-level — stderr
        console.error(`▲  ${state.reason}${status} — retrying attempt ${state.attempt}/${state.maxRetries}${eta > 0 ? ` in ${eta}s` : ''}`);
    }
    startRun() {
        // No-op in CI mode
    }
    setRunError(_error) {
        // No retry in CI — let the caller fall through to wizardAbort
        return Promise.resolve(false);
    }
    setCredentials(_credentials) {
        // No-op in CI mode — credentials are handled directly
    }
    setRegion(_region) {
        // No-op in CI mode
    }
    setProjectHasData(_value) {
        // No-op in CI mode
    }
    promptConfirm(message) {
        console.log(`?  ${message} (auto-skipped in CI)`);
        return Promise.resolve(false);
    }
    promptChoice(message, options) {
        console.log(`?  ${message} (auto-skipped in CI)`);
        console.log(`│  Options: ${options.join(', ')}`);
        return Promise.resolve('');
    }
    promptEventPlan(events) {
        console.log(`?  Instrumentation plan (auto-approved in CI):`);
        for (const e of events) {
            console.log(`│  - ${e.name}: ${e.description}`);
        }
        return Promise.resolve({ decision: 'approved' });
    }
    syncTodos(todos) {
        const completed = todos.filter((t) => t.status === wizard_ui_1.TaskStatus.Completed).length;
        const inProgress = todos.find((t) => t.status === wizard_ui_1.TaskStatus.InProgress);
        if (inProgress) {
            console.log(`◌  [${completed}/${todos.length}] ${inProgress.activeForm || inProgress.content}`);
        }
    }
    applyJourneyTransition(stepId, status) {
        console.log(`◌  journey: ${stepId} ${status}`);
    }
    setEventPlan(_events) {
        // No-op in CI mode
    }
    recordFileChangePlanned(data) {
        // CI logs the plan-then-apply pair as a single line per file. Verbose
        // enough to be useful when scanning a CI run, quiet enough not to drown
        // out the rest of the output.
        console.log(`◌  ${data.operation} ${data.path}`);
    }
    recordFileChangeApplied(_data) {
        // The planned-line above already announced the write. Skip the applied
        // line in CI to avoid doubling the per-file output volume.
    }
    setEventIngestionDetected(_eventNames) {
        // No-op in CI/logging mode
    }
    setDashboardUrl(_url) {
        // No-op in CI/logging mode
    }
}
exports.LoggingUI = LoggingUI;
