import path from "path";
import fs from "fs-extra";
import chalk from "chalk";
import type { PackageManager } from "@turbo/workspaces";
import type { CreateCommandArgument, CreateCommandOptions } from "./types";
import { getAvailablePackageManagers } from "turbo-utils";
import { isFolderEmpty } from "../../utils/isFolderEmpty";
import inquirer from "inquirer";

function validateDirectory(directory: string): {
  valid: boolean;
  root: string;
  projectName: string;
  error?: string;
} {
  const root = path.resolve(directory);
  const projectName = path.basename(root);
  const exists = fs.existsSync(root);

  const stat = fs.lstatSync(root, { throwIfNoEntry: false });
  if (stat && !stat.isDirectory()) {
    return {
      valid: false,
      root,
      projectName,
      error: `${chalk.dim(
        projectName
      )} is not a directory - please try a different location`,
    };
  }

  if (exists) {
    const { isEmpty, conflicts } = isFolderEmpty(root);
    if (!isEmpty) {
      return {
        valid: false,
        root,
        projectName,
        error: `${chalk.dim(projectName)} has ${conflicts.length} conflicting ${
          conflicts.length === 1 ? "file" : "files"
        } - please try a different location`,
      };
    }
  }

  return { valid: true, root, projectName };
}

export async function directory({
  directory,
}: {
  directory: CreateCommandArgument;
}) {
  const projectDirectoryAnswer = await inquirer.prompt<{
    projectDirectory: string;
  }>({
    type: "input",
    name: "projectDirectory",
    message: "Where would you like to create your turborepo?",
    when: !directory,
    default: "./my-turborepo",
    validate: (directory: string) => {
      const { valid, error } = validateDirectory(directory);
      if (!valid && error) {
        return error;
      }
      return true;
    },
    filter: (directory: string) => directory.trim(),
  });

  const { projectDirectory: selectedProjectDirectory = directory as string } =
    projectDirectoryAnswer;

  return validateDirectory(selectedProjectDirectory);
}

export async function packageManager({
  packageManager,
  skipTransforms,
}: {
  packageManager: CreateCommandArgument;
  skipTransforms?: boolean;
}) {
  // if skip transforms is passed, we don't need to ask about the package manager (because that requires a transform)
  if (skipTransforms) {
    return undefined;
  }

  const availablePackageManagers = await getAvailablePackageManagers();
  const packageManagerAnswer = await inquirer.prompt<{
    packageManagerInput?: PackageManager;
  }>({
    name: "packageManagerInput",
    type: "list",
    message: "Which package manager do you want to use?",
    when:
      !packageManager ||
      !Object.keys(availablePackageManagers).includes(packageManager),
    choices: ["npm", "pnpm", "yarn"].map((p) => ({
      name: p,
      value: p,
      disabled: availablePackageManagers?.[p as PackageManager]?.available
        ? false
        : `not installed`,
    })),
  });

  const {
    packageManagerInput:
      selectedPackageManager = packageManager as PackageManager,
  } = packageManagerAnswer;

  return {
    name: selectedPackageManager,
    version: availablePackageManagers[selectedPackageManager].version,
  };
}
