"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const node_fs_1 = require("node:fs");
const path = __importStar(require("node:path"));
const api_client_1 = require("../../lib/api-client");
const config_storage_1 = require("../../lib/config-storage");
const prompts_1 = require("../../lib/prompts");
class IntegrationSetupGithubApp extends core_1.Command {
    async run() {
        const { flags } = await this.parse(IntegrationSetupGithubApp);
        const configStorage = new config_storage_1.ConfigStorage();
        const apiUrl = configStorage.getApiUrlOrThrow();
        const apiKey = configStorage.getApiKey();
        if (!apiKey) {
            this.error('Not logged in. Run `flui auth login` first.', { exit: 1 });
        }
        const api = new api_client_1.ApiClient({ baseUrl: apiUrl, apiKey });
        let status = null;
        try {
            status = await api.get('/repositories/github/setup/status');
        }
        catch {
            /* empty */
        }
        if (status?.configured) {
            console.log(chalk_1.default.yellow(`\n  GitHub integration is already configured (authMethod=${status.authMethod}${status.appSlug ? `, appSlug=${status.appSlug}` : ''}).`));
            const ok = await (0, prompts_1.confirmPrompt)('Overwrite the existing configuration?', false);
            if (!ok) {
                console.log(chalk_1.default.dim('\n  Cancelled.\n'));
                return;
            }
        }
        console.log(chalk_1.default.dim('\n  Get these values from https://github.com/settings/apps/<your-app>\n'));
        const appId = await (0, prompts_1.promptInput)({
            message: 'App ID',
            validate: (v) => /^\d+$/.test(v) ? null : 'App ID must be a numeric string',
        });
        const appSlug = await (0, prompts_1.promptInput)({
            message: 'App slug (last segment of the app URL)',
            default: 'flui-cloud',
        });
        const clientId = await (0, prompts_1.promptInput)({
            message: 'Client ID (e.g. Iv23...)',
        });
        const clientSecret = await (0, prompts_1.promptMaskedInput)('Client Secret');
        if (!clientSecret) {
            this.error('Client Secret cannot be empty', { exit: 1 });
        }
        const webhookSecret = await (0, prompts_1.promptMaskedInput)('Webhook Secret');
        if (!webhookSecret) {
            this.error('Webhook Secret cannot be empty', { exit: 1 });
        }
        const privateKeyFile = flags['private-key-file'] ??
            (await (0, prompts_1.promptInput)({
                message: 'Path to private key (.pem) file',
                validate: (v) => (v.endsWith('.pem') ? null : 'Expected a .pem file'),
            }));
        let privateKey;
        try {
            const resolved = path.isAbsolute(privateKeyFile)
                ? privateKeyFile
                : path.resolve(process.cwd(), privateKeyFile);
            privateKey = await node_fs_1.promises.readFile(resolved, 'utf-8');
        }
        catch (err) {
            this.error(`Failed to read private key from "${privateKeyFile}": ${err.message}`, { exit: 1 });
        }
        if (!privateKey.includes('BEGIN') || !privateKey.includes('PRIVATE KEY')) {
            this.error(`File "${privateKeyFile}" does not look like a PEM private key`, { exit: 1 });
        }
        const defaultCallback = `${apiUrl.replace(/\/$/, '')}/repositories/github-app/user-callback`;
        const callbackUrl = flags['callback-url'] ??
            (await (0, prompts_1.promptInput)({
                message: 'Callback URL (must match the GitHub App setting)',
                default: defaultCallback,
            }));
        const payload = {
            appId,
            privateKey,
            webhookSecret,
            appSlug,
            clientId,
            clientSecret,
            callbackUrl,
        };
        const spinner = (0, ora_1.default)('Saving GitHub App configuration…').start();
        try {
            await api.post('/repositories/github/setup/github-app', payload);
            spinner.succeed('GitHub App configured');
        }
        catch (error) {
            spinner.fail('Failed to save configuration');
            if (error instanceof api_client_1.ApiError) {
                console.log(chalk_1.default.red(`  ${error.statusCode}: ${error.message}`));
                if (error.statusCode === 403) {
                    console.log(chalk_1.default.yellow('  Admin privileges required for this operation.'));
                }
            }
            else {
                console.log(chalk_1.default.red(`  ${error.message}`));
            }
            this.exit(1);
        }
        console.log('');
        console.log(chalk_1.default.dim(`  Verify with: ${chalk_1.default.cyan('flui integration installations')}`));
        console.log(chalk_1.default.dim(`  Connect a user with: ${chalk_1.default.cyan('flui integration connect github')}`));
        console.log('');
    }
}
IntegrationSetupGithubApp.description = 'Configure the GitHub App credentials in Flui (admin only). Interactively prompts for App ID, slug, client ID/secret, webhook secret and private key path. Secrets are hidden during input and encrypted at rest in the database.';
IntegrationSetupGithubApp.examples = [
    '<%= config.bin %> <%= command.id %>',
    '<%= config.bin %> <%= command.id %> --private-key-file ./flui-cloud.pem',
];
IntegrationSetupGithubApp.flags = {
    'private-key-file': core_1.Flags.string({
        description: 'Path to the GitHub App private key PEM file (skips the path prompt)',
    }),
    'callback-url': core_1.Flags.string({
        description: 'OAuth callback URL configured on the GitHub App. Defaults to <api-url>/repositories/github-app/user-callback',
    }),
};
exports.default = IntegrationSetupGithubApp;
