import select from '@inquirer/select';
import { Command, Flags } from '@oclif/core';
import chalk from 'chalk';
import ora from 'ora';
import { loadConfig } from '../../deploy/domain/config.js';
import { initializeSheetsApi } from '../../sheets/domain/auth.js';
import { pullBoundedContext } from '../../sheets/sync/sheet-to-yaml.js';
export default class Pull extends Command {
    static description = 'Pull schemas from Google Sheets to Aurora YAML files.';
    static examples = [
        '<%= config.bin %> sheets pull --bc iam',
        '<%= config.bin %> sheets pull --all',
        '<%= config.bin %> sheets pull --all --no-backup',
        '<%= config.bin %> sheets pull --bc iam --dry-run',
    ];
    static flags = {
        all: Flags.boolean({
            description: 'Pull all bounded contexts',
            exclusive: ['bc'],
        }),
        bc: Flags.string({
            description: 'Bounded context name',
        }),
        config: Flags.string({
            char: 'c',
            default: './aurora.yaml',
            description: 'Path to aurora.yaml config file',
        }),
        'dry-run': Flags.boolean({
            description: 'Preview without making changes',
        }),
        'no-backup': Flags.boolean({
            description: 'Skip creating backup before pull',
        }),
        verbose: Flags.boolean({
            char: 'v',
            description: 'Show detailed output',
        }),
    };
    async run() {
        const { flags } = await this.parse(Pull);
        const config = loadConfig(flags.config);
        if (!config.sheets) {
            this.error('No "sheets" section found in aurora.yaml.\n' +
                'Add a sheets.bounded_contexts block to your config.');
        }
        const allNames = Object.keys(config.sheets.boundedContexts);
        if (allNames.length === 0) {
            this.error('No bounded contexts configured in sheets section.');
        }
        let boundedContexts;
        if (flags.all) {
            boundedContexts = allNames;
        }
        else if (flags.bc) {
            if (!config.sheets.boundedContexts[flags.bc]) {
                this.error(`Bounded context "${flags.bc}" not found.\nAvailable: ${allNames.join(', ')}`);
            }
            boundedContexts = [flags.bc];
        }
        else {
            const selected = await select({
                choices: allNames.map((name) => ({
                    description: config.sheets.boundedContexts[name].description,
                    name,
                    value: name,
                })),
                message: 'Select a bounded context to pull:',
            });
            boundedContexts = [selected];
        }
        const spinner = ora();
        const sheetsApi = await this.initAuth(spinner);
        let hasErrors = false;
        for (const bc of boundedContexts) {
            spinner.start(`Pulling: ${bc}`);
            const bcConfig = config.sheets.boundedContexts[bc];
            // eslint-disable-next-line no-await-in-loop
            const result = await pullBoundedContext({
                backupsPath: './backups/aurora-schemas',
                boundedContextName: bc,
                cliterPath: './cliter',
                sheetsApi,
                spreadsheetId: bcConfig.spreadsheetId,
            }, {
                backup: !flags['no-backup'],
                dryRun: flags['dry-run'],
                verbose: flags.verbose,
            });
            if (result.success) {
                spinner.succeed(`Pulled: ${bc} (${result.modulesProcessed} modules)`);
            }
            else {
                spinner.fail(`Pull failed: ${bc}`);
                hasErrors = true;
            }
            for (const msg of result.messages) {
                this.log(`  ${msg}`);
            }
        }
        if (hasErrors) {
            this.error('Some bounded contexts failed to pull.');
        }
        this.log(chalk.green('\nPull completed successfully!'));
    }
    async initAuth(spinner) {
        spinner.start('Authenticating with Google Sheets...');
        try {
            const api = await initializeSheetsApi();
            spinner.succeed('Authenticated with Google Sheets');
            return api;
        }
        catch (error) {
            spinner.fail('Authentication failed');
            throw error;
        }
    }
}
