import fs from "node:fs/promises"
import path from "node:path"
import chalk from "chalk"
import { checkbox, confirm, select } from "@inquirer/prompts"
import type { Chain } from "./types"

export const chainOptions = [
	{
		name: "Ethereum",
		package: "@dynamic-labs/ethereum",
		connector: "EthereumWalletConnectors",
	},
	{
		name: "Algorand",
		package: "@dynamic-labs/algorand",
		connector: "AlgorandWalletConnectors",
	},
	{
		name: "Solana",
		package: "@dynamic-labs/solana",
		connector: "SolanaWalletConnectors",
	},
	{
		name: "Flow",
		package: "@dynamic-labs/flow",
		connector: "FlowWalletConnectors",
	},
	{
		name: "Starknet",
		package: "@dynamic-labs/starknet",
		connector: "StarknetWalletConnectors",
	},
	{
		name: "Cosmos",
		package: "@dynamic-labs/cosmos",
		connector: "CosmosWalletConnectors",
	},
	{
		name: "Bitcoin",
		package: "@dynamic-labs/bitcoin",
		connector: "BitcoinWalletConnectors",
	},
	{
		name: "Sui",
		package: "@dynamic-labs/sui",
		connector: "SuiWalletConnectors",
	},
]

export const promptForChains = async (): Promise<Chain[]> => {
	const chainChoices = chainOptions.map((chain, index) => ({
		name: chain.name,
		value: index,
	}))

	while (true) {
		const selectedChainIndices = await checkbox({
			message: "Select the chains you want to include:",
			choices: chainChoices,
		})

		if (selectedChainIndices.length === 0) {
			console.log(chalk.yellow("Warning: No chains selected."))
			const action = await select({
				message:
					"Do you want to continue without selecting any chains or go back to the selection?",
				choices: [
					{ name: "Continue without chains", value: "continue" },
					{ name: "Go back to chain selection", value: "back" },
				],
			})

			if (action === "continue") {
				return []
			}
			// If 'back' is selected, the loop will continue and prompt again
		} else {
			return selectedChainIndices
				.map((index: number) => chainOptions[index])
				.filter((chain): chain is Chain => chain !== undefined)
		}
	}
}

export const checkExistingDirectories = async (
	appNames: string | string[],
	parentDir: string
) => {
	const existingDirs = []
	const names = Array.isArray(appNames) ? appNames : [appNames]

	for (const name of names) {
		try {
			await fs.access(path.join(parentDir, name))
			existingDirs.push(name)
		} catch {
			// Directory doesn't exist, which is fine
		}
	}

	if (existingDirs.length > 0) {
		console.log(
			chalk.yellow(
				`The following directories already exist: ${existingDirs.join(", ")}`
			)
		)
		const overwrite = await confirm({
			message: "Do you want to overwrite these directories?",
			default: false,
		})

		if (!overwrite) {
			console.log(chalk.red("Operation cancelled."))
			process.exit(0)
		} else {
			for (const dir of existingDirs) {
				await fs.rm(path.join(parentDir, dir), {
					recursive: true,
					force: true,
				})
			}
		}
	} else {
		console.log(chalk.green("All directories are available for creation."))
	}
}
