// packages/cli/src/commands/login.ts
import { Command, Flags } from '@oclif/core';
import { chromium } from 'playwright-core';
import { setKey, getAuthContext, getConfig, withCliPathPrefix, LOGIN_PATH, LOGIN_PATH_PASSWORD, ERPLOGIN_PATH, KEY_PARAM, LOGIN_TIMEOUT_MS } from '@mb-it-org/shared';
const MISSING_BROWSER_MESSAGE = 'No supported browser runtime is available';
const MISSING_BROWSER_HINT = 'Make sure Chrome or Edge is installed and available, then try `mbs login` again. Only install an extra browser runtime if the system browsers cannot be used.';
function isMissingChromiumError(error) {
    if (!(error instanceof Error))
        return false;
    const message = error.message.toLowerCase();
    return (message.includes("executable doesn't exist") ||
        (message.includes('browser') && message.includes('executable')) ||
        message.includes('playwright install'));
}
async function launchBrowser() {
    const launchOptions = [
        { channel: 'chrome', headless: false },
        { channel: 'msedge', headless: false },
        { headless: false },
    ];
    let lastError;
    for (const options of launchOptions) {
        try {
            return await chromium.launch(options);
        }
        catch (error) {
            lastError = error;
        }
    }
    throw lastError;
}
export default class Login extends Command {
    static description = 'Authenticate with the MBS system via browser';
    static examples = ['mbs login', 'mbs login --password'];
    static flags = {
        password: Flags.boolean({
            char: 'p',
            description: 'Login with username and password instead of QR code',
            default: false,
        }),
    };
    async run() {
        const { flags } = await this.parse(Login);
        const { apiUrl } = getConfig();
        const loginUrl = withCliPathPrefix(apiUrl, flags.password ? LOGIN_PATH_PASSWORD : LOGIN_PATH);
        this.log('Opening browser for authentication...');
        this.log(`URL: ${loginUrl}`);
        let browser;
        try {
            browser = await launchBrowser();
        }
        catch (error) {
            if (isMissingChromiumError(error)) {
                this.log(JSON.stringify({
                    ok: false,
                    error: {
                        type: 'validation',
                        message: MISSING_BROWSER_MESSAGE,
                        hint: MISSING_BROWSER_HINT,
                    },
                }));
                this.exit(1);
                return;
            }
            throw error;
        }
        try {
            const context = await browser.newContext();
            const page = await context.newPage();
            const key = await new Promise((resolve, reject) => {
                const timeout = setTimeout(() => reject(new Error('Login timeout — please try again')), LOGIN_TIMEOUT_MS);
                page.on('request', request => {
                    if (request.url().includes(ERPLOGIN_PATH)) {
                        const url = new URL(request.url());
                        const keyValue = url.searchParams.get(KEY_PARAM);
                        if (keyValue) {
                            clearTimeout(timeout);
                            resolve(keyValue);
                        }
                    }
                });
                // Navigate to login page AFTER attaching listener to avoid race condition
                void page.goto(loginUrl);
            });
            await setKey(key);
            // Immediately fetch and cache cookie + userInfo
            await getAuthContext();
            this.log(JSON.stringify({ ok: true, data: { message: 'Authenticated successfully' } }));
        }
        finally {
            await browser.close();
        }
    }
}
//# sourceMappingURL=login.js.map