import { select } from "@inquirer/prompts";
import { logger } from "../common/logger.js";
import { printCriticalFailureToConsoleAndExit, printResultToConsoleAndExitGracefully, textOrJson, } from "../common/output.js";
import settings from "../common/settings.js";
import { pullSystemConfig, safeMergeConfig } from "./populate.js";
function prettyPrintEnvironmentPrompt(env, hasSingleDevelopmentInstance) {
    let environmentType = env.environmentType.toLowerCase();
    let branchName = env.branchName;
    let name = env.name;
    switch (environmentType) {
        case "working-copy":
        case "working_copy":
        case "development":
            if (hasSingleDevelopmentInstance) {
                name = "Default for local development";
                environmentType = "development";
                branchName = "";
                return `${name} (${environmentType})`;
            }
            else {
                environmentType = "development";
                branchName = "";
                return `${name} (${environmentType})`;
            }
    }
    return `${name} (${environmentType}, ${branchName})`;
}
export async function link(argv) {
    const account = argv.account;
    let environment = argv.environment;
    let project = argv.project;
    if (!environment && !project) {
        const projectResponse = await fetch(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/projects`, {
            headers: {
                authorization: `Bearer ${argv.authToken}`,
            },
        });
        if (!projectResponse.ok) {
            logger.error({
                status: projectResponse.status,
                statusText: projectResponse.statusText,
                response: textOrJson(await projectResponse.text()),
            }, "Failed to list projects.");
            await printCriticalFailureToConsoleAndExit("Error: Failed to list your projects. Try again later.");
        }
        const projectJson = (await projectResponse.json());
        if (projectJson.data.length === 1) {
            project = projectJson.data[0].name;
        }
        else {
            project = await select({
                message: "Select the project to work with",
                choices: projectJson.data.map((prj) => {
                    return {
                        name: prj.name,
                        value: prj.name,
                    };
                }),
            });
        }
    }
    if (!environment) {
        const baseUrl = `${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/environments`;
        const queryParams = {
            accountName: account,
            projectName: project,
        };
        const url = new URL(baseUrl);
        url.search = new URLSearchParams(queryParams).toString();
        let environmentResponseFromDeveloperAPI = await fetch(url, {
            headers: {
                authorization: `Bearer ${argv.authToken}`,
            },
        });
        if (!environmentResponseFromDeveloperAPI.ok) {
            logger.error({
                status: environmentResponseFromDeveloperAPI.status,
                statusText: environmentResponseFromDeveloperAPI.statusText,
            }, "Failed to link to a project in your account");
            await printCriticalFailureToConsoleAndExit("Check that the project specified in your zuplo.jsonc exists and that you have access to it.");
        }
        let environmentJsonFromDeveloperAPI = (await environmentResponseFromDeveloperAPI.json());
        let numDevelopmentEnvironments = environmentJsonFromDeveloperAPI.data.filter((env) => {
            return env.environmentType === "development";
        }).length;
        if (numDevelopmentEnvironments <= 0) {
            const createDevelopmenEnvironmentResponse = await fetch(`${baseUrl}`, {
                method: "POST",
                headers: {
                    authorization: `Bearer ${argv.authToken}`,
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    accountName: account,
                    projectName: project,
                    environmentType: "development",
                }),
            });
            if (!createDevelopmenEnvironmentResponse.ok) {
                logger.debug({
                    status: createDevelopmenEnvironmentResponse.status,
                    statusText: createDevelopmenEnvironmentResponse.statusText,
                }, "Failed to create a new instance of development environment");
                await printCriticalFailureToConsoleAndExit("Failed to create a new development environment. Please try again later.");
            }
            numDevelopmentEnvironments++;
            environmentResponseFromDeveloperAPI = await fetch(url, {
                headers: {
                    authorization: `Bearer ${argv.authToken}`,
                },
            });
            environmentJsonFromDeveloperAPI =
                (await environmentResponseFromDeveloperAPI.json());
        }
        const environments = Object.assign({}, environmentJsonFromDeveloperAPI.data
            .map((env) => {
            return {
                [prettyPrintEnvironmentPrompt(env, numDevelopmentEnvironments == 1)]: env.name,
            };
        })
            .reduce((acc, curr) => {
            return { ...acc, ...curr };
        }));
        if (Object.values(environments).length === 1) {
            environment = Object.values(environments)[0];
        }
        else {
            environment = await select({
                message: "Select the environment to work with",
                choices: Object.entries(environments).map(([key, value]) => {
                    return {
                        name: key,
                        value,
                    };
                }),
            });
        }
    }
    argv.environment = environment;
    if (project) {
        await safeMergeConfig(argv.dir, project);
    }
    await pullSystemConfig(argv);
    await printResultToConsoleAndExitGracefully(`
Successfully linked your local directory to the ${project} project in the ${account} account.
.env.zuplo and zuplo.jsonc have been updated with the new values.`);
}
//# sourceMappingURL=handler.js.map