import { Command, flags } from '@heroku-cli/command';
import { color, hux } from '@heroku/heroku-cli-util';
import { ux } from '@oclif/core/ux';
export default class UsageAddons extends Command {
    static description = 'list usage for metered add-ons attached to an app or apps within a team';
    static flags = {
        app: flags.string({ char: 'a', description: 'app to list metered add-ons usage for' }),
        team: flags.team({ description: 'team to list metered add-ons usage for' }),
    };
    static topic = 'usage';
    async run() {
        const { flags } = await this.parse(UsageAddons);
        const { app, team } = flags;
        if (!app && !team) {
            ux.error('Specify an app with --app or a team with --team');
        }
        if (app) {
            await this.fetchAndDisplayAppUsageData(app, team);
        }
        else if (team) {
            await this.fetchAndDisplayTeamUsageData(team);
        }
    }
    displayAppUsage(app, usageAddons, appAddons) {
        const metersArray = usageAddons.flatMap(addon => Object.entries(addon.meters).map(([label, data]) => ({
            addonId: addon.id,
            label,
            quantity: data.quantity,
        })));
        hux.styledHeader(`Usage for ${color.app(app)}`);
        hux.table(metersArray, {
            'Add-on': {
                get(row) {
                    const matchingAddon = appAddons.find(a => a.id === row.addonId);
                    return matchingAddon?.name || row.addonId;
                },
            },
            Meter: {
                get: row => row.label,
            },
            Quantity: {
                get: row => row.quantity,
            },
        });
    }
    async fetchAndDisplayAppUsageData(app, team) {
        let usageData;
        let appAddons;
        ux.action.start('Gathering usage data');
        if (team) {
            [{ body: usageData }, { body: appAddons }] = await Promise.all([
                this.heroku.get(`/teams/${team}/apps/${app}/usage`, {
                    headers: {
                        Accept: 'application/vnd.heroku+json; version=3.sdk',
                    },
                }),
                this.heroku.get(`/apps/${app}/addons`),
            ]);
        }
        else {
            [{ body: usageData }, { body: appAddons }] = await Promise.all([
                this.heroku.get(`/apps/${app}/usage`, {
                    headers: {
                        Accept: 'application/vnd.heroku+json; version=3.sdk',
                    },
                }),
                this.heroku.get(`/apps/${app}/addons`),
            ]);
        }
        ux.action.stop();
        ux.stdout();
        const usageAddons = usageData.addons;
        if (usageAddons.length === 0) {
            ux.stdout(`No usage found for app ${color.app(app)}`);
            return;
        }
        this.displayAppUsage(app, usageAddons, appAddons);
    }
    async fetchAndDisplayTeamUsageData(team) {
        ux.action.start(`Gathering usage data for ${color.team(team)}`);
        const [{ body: usageData }, { body: teamAddons }] = await Promise.all([
            this.heroku.get(`/teams/${team}/usage`, {
                headers: {
                    Accept: 'application/vnd.heroku+json; version=3.sdk',
                },
            }),
            this.heroku.get(`/teams/${team}/addons`),
        ]);
        ux.action.stop();
        ux.stdout();
        if (!usageData.apps || usageData.apps.length === 0) {
            ux.stdout(`No usage found for team ${color.team(team)}`);
            return;
        }
        const appInfoArray = this.getAppInfoFromTeamAddons(teamAddons);
        // Display usage for each app
        usageData.apps.forEach((app) => {
            const appInfo = appInfoArray.find(info => info.id === app.id);
            this.displayAppUsage(appInfo?.name || app.id, app.addons, teamAddons);
            ux.stdout();
        });
    }
    getAppInfoFromTeamAddons(teamAddons) {
        const appInfoMap = new Map();
        teamAddons.forEach(addon => {
            if (addon.app && addon.app.id && addon.app.name) {
                appInfoMap.set(addon.app.id, addon.app.name);
            }
        });
        return Array.from(appInfoMap.entries()).map(([id, name]) => ({
            id,
            name,
        }));
    }
}
