import chalk from "chalk";
import ora from "ora";
import { Command, Option } from "commander";
import { getUrlAndAdminKey } from "./lib/api.js";
import { validateOrSelectProject, validateOrSelectTeam } from "./lib/utils.js";
import {
  configName,
  pullConfig,
  readProjectConfig,
  writeProjectConfig,
} from "./lib/config.js";
import { oneoffContext } from "./lib/context.js";
import { doCodegen } from "./lib/codegen.js";

export const reinit = new Command("reinit")
  .description(
    "Reinitialize a Convex project in the local directory if you've lost your convex.json file"
  )
  .addOption(
    new Option(
      "--team <team_slug>",
      "The identifier of the team the project belongs to."
    )
  )
  .addOption(
    new Option(
      "--project <project_slug>",
      "The identifier of the project you'd like to reinitialize."
    )
  )
  .action(async options => {
    const ctx = oneoffContext;
    const configFn = configName();
    if (ctx.fs.exists(configFn)) {
      console.error(chalk.red(`File "${configFn}" already exists.`));
      console.error(
        "If you'd like to regenerate it, delete the file and rerun `npx convex reinit`"
      );
      return await ctx.fatalError(1, "fs");
    }

    const teamSlug = await validateOrSelectTeam(
      ctx,
      options.team,
      "Choose which team the project belongs to:"
    );

    const projectSlug = await validateOrSelectProject(
      ctx,
      options.project,
      teamSlug,
      "Reinitialize project:",
      "Choose which project to reinitialize:"
    );
    if (!projectSlug) {
      console.log("Aborted");
      return;
    }
    const spinner = ora({
      text: `Reinitializing project ${projectSlug}...\n`,
      stream: process.stdout,
    }).start();

    const { url, adminKey } = await getUrlAndAdminKey(
      ctx,
      projectSlug,
      teamSlug,
      "prod"
    );
    {
      const { projectConfig } = await pullConfig(
        ctx,
        projectSlug,
        teamSlug,
        url,
        adminKey
      );
      await writeProjectConfig(ctx, projectConfig);
    }

    const { projectConfig, configPath } = await readProjectConfig(ctx);
    await doCodegen({
      ctx,
      projectConfig,
      configPath,
      deploymentType: "dev",
      typeCheckMode: "disable",
      quiet: true,
    });

    spinner.succeed(`Successfully reinitialized ${projectSlug}!`);
    console.log(
      "Configuration settings have been written to",
      chalk.bold(configFn)
    );
  });
