"use strict";
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 api_client_1 = require("../../lib/api-client");
const config_storage_1 = require("../../lib/config-storage");
const resolve_cluster_1 = require("../../lib/resolve-cluster");
const prompts_1 = require("../../lib/prompts");
const POLL_INTERVAL_MS = 5000;
const MAX_WAIT_MS = 600_000;
class ClusterDestroy extends core_1.Command {
    async run() {
        const { args, flags } = await this.parse(ClusterDestroy);
        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 });
        }
        let resolved;
        try {
            resolved = await (0, resolve_cluster_1.resolveCluster)(args.cluster);
        }
        catch (error) {
            this.error(error.message, { exit: 1 });
        }
        const { id: clusterId, name: clusterName, entity } = resolved;
        if (entity.metadata?.isObservabilityCluster) {
            this.error(`"${clusterName}" is the observability cluster. Use \`flui env destroy\` instead.`, { exit: 1 });
        }
        console.log(chalk_1.default.red('\n⚠️  DESTROY Workload Cluster\n'));
        console.log(`  ${chalk_1.default.bold('Name:')}    ${clusterName}`);
        console.log(`  ${chalk_1.default.bold('ID:')}      ${clusterId}`);
        console.log(`  ${chalk_1.default.bold('Status:')}  ${entity.status}`);
        console.log(`  ${chalk_1.default.bold('Region:')}  ${entity.region}`);
        console.log(`  ${chalk_1.default.bold('Nodes:')}   ${entity.nodeCount}`);
        console.log(chalk_1.default.red('\n  ⚠️  ALL DATA WILL BE PERMANENTLY LOST!\n'));
        if (!flags.force) {
            console.log(chalk_1.default.yellow(`  To confirm, type the cluster name exactly: ${chalk_1.default.bold(clusterName)}`));
            const confirmed = await (0, prompts_1.confirmByTypingPrompt)(chalk_1.default.yellow('  Cluster name'), clusterName);
            if (!confirmed) {
                console.log(chalk_1.default.green('\n  Deletion cancelled (name did not match)\n'));
                return;
            }
        }
        const spinner = (0, ora_1.default)('Queuing cluster deletion...').start();
        const apiClient = new api_client_1.ApiClient({ baseUrl: apiUrl, apiKey: apiKey });
        let operationId;
        try {
            const result = await apiClient.delete(`/infrastructure/clusters/${clusterId}`);
            operationId = result.operation_id;
            spinner.succeed('Deletion queued');
            console.log('');
            console.log(`  ${chalk_1.default.bold('Operation ID:')} ${operationId}`);
            console.log(`  ${chalk_1.default.bold('Estimated:')}    ${result.estimated_duration}`);
            console.log('');
        }
        catch (error) {
            spinner.fail('Failed to queue deletion');
            const msg = error.response?.data?.message ?? error.message;
            console.log(chalk_1.default.red(`\n  Error: ${msg}\n`));
            this.exit(1);
        }
        if (flags['no-wait']) {
            console.log(chalk_1.default.dim('  Use `flui node list --cluster <name>` to check status.\n'));
            return;
        }
        await this.waitForDeletion(apiClient, operationId, clusterName);
    }
    async waitForDeletion(apiClient, operationId, clusterName) {
        console.log(chalk_1.default.dim(`  Waiting for deletion to complete (up to ${MAX_WAIT_MS / 60000} min)…`));
        const waitSpinner = (0, ora_1.default)('Deleting cluster…').start();
        const started = Date.now();
        while (Date.now() - started < MAX_WAIT_MS) {
            await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
            const done = await this.pollOperation(apiClient, operationId, clusterName, waitSpinner);
            if (done)
                return;
        }
        waitSpinner.warn('Timed out waiting for deletion');
        console.log(chalk_1.default.yellow(`\n  Operation is still running. Check status with:`));
        console.log(chalk_1.default.dim(`    flui node list --cluster ${clusterName}\n`));
    }
    async pollOperation(apiClient, operationId, clusterName, waitSpinner) {
        try {
            const op = await apiClient.get(`/infrastructure/operations/${operationId}`);
            const pct = op.totalSteps > 0
                ? Math.round((op.currentStepIndex / op.totalSteps) * 100)
                : 0;
            waitSpinner.text = `Deleting cluster… ${pct}% (step ${op.currentStepIndex}/${op.totalSteps})`;
            if (op.status === 'COMPLETED') {
                waitSpinner.succeed(chalk_1.default.green(`Cluster "${clusterName}" destroyed`));
                console.log('');
                console.log(chalk_1.default.dim('  All nodes and associated resources have been removed.\n'));
                return true;
            }
            if (op.status === 'FAILED') {
                waitSpinner.fail('Deletion failed');
                const msg = op.metadata?.error ?? 'Unknown error';
                console.log(chalk_1.default.red(`\n  Error: ${msg}\n`));
                this.exit(1);
            }
        }
        catch {
            /* polling error — keep trying */
        }
        return false;
    }
}
ClusterDestroy.description = 'Permanently destroy a workload cluster and all its nodes. For the observability cluster use `flui env destroy`.';
ClusterDestroy.examples = [
    '<%= config.bin %> <%= command.id %> my-workload-cluster',
    '<%= config.bin %> <%= command.id %> my-workload-cluster --force',
    '<%= config.bin %> <%= command.id %> my-workload-cluster --no-wait',
];
ClusterDestroy.args = {
    cluster: core_1.Args.string({
        description: 'Cluster name or ID to destroy',
        required: true,
    }),
};
ClusterDestroy.flags = {
    force: core_1.Flags.boolean({
        char: 'f',
        description: 'Skip confirmation prompt',
        default: false,
    }),
    'no-wait': core_1.Flags.boolean({
        description: 'Return immediately after queuing deletion',
        default: false,
    }),
};
exports.default = ClusterDestroy;
