import { select } from "@inquirer/prompts"
import { run as runNew } from "./commands/new.js"
import { run as runDev } from "./commands/dev.js"
import { run as runExport } from "./commands/export.js"
import { run as runDelete } from "./commands/delete.js"
import { showBanner, pickDeck } from "./ui.js"
import { listDecks, EXAMPLE_DECKS } from "./utils/decks.js"

const BACK = "__back__"

;(async () => {
  const command = process.argv[2]

  if (command) {
    const commands = {
      new: runNew,
      dev: runDev,
      export: runExport,
      delete: runDelete,
    }
    const handler = commands[command as keyof typeof commands]
    if (!handler) {
      console.error(`Unknown command: ${command}`)
      console.error("Available commands: new, dev, export, delete")
      process.exit(1)
    }
    await handler(process.argv[3])
  } else {
    await showBanner()

    const isExitError = (e: unknown) =>
      e instanceof Error && e.name === "ExitPromptError"

    while (true) {
      let custom: string[], examples: string[], picked: Awaited<ReturnType<typeof pickDeck>>
      try {
        ;({ custom, examples } = await listDecks())
        picked = await pickDeck({ custom, examples })
      } catch (e) {
        if (isExitError(e)) break
        throw e
      }

      if (!picked) break

      if (picked.action === "new") {
        await runNew()
        continue
      }

      if (picked.action === "delete") {
        await runDelete(picked.deck)
        continue
      }

      const deck = picked.deck
      const isExample = EXAMPLE_DECKS.has(deck)

      while (true) {
        let action: string
        try {
          action = await select({
            message: `${deck} — what do you want to do?`,
            choices: [
              {
                name: "Preview",
                value: "dev",
                description: "Open in browser with live reload",
              },
              {
                name: "Export",
                value: "export",
                description: "Export to PDF or PNG",
              },
              ...(!isExample
                ? [
                    {
                      name: "Delete",
                      value: "delete",
                      description: "Permanently remove this deck",
                    },
                  ]
                : []),
              { name: "← Back", value: BACK },
            ],
          })
        } catch (e) {
          if (isExitError(e)) break
          throw e
        }

        if (action === BACK) break
        if (action === "dev") await runDev(deck)
        else if (action === "export") await runExport(deck)
        else {
          await runDelete(deck)
          break
        }
      }
    }
  }
})().catch((e) => {
  if (e instanceof Error && e.name !== "ExitPromptError") console.error(e)
  process.exit(1)
})
