/**
 * storyboard workleaf — dispatch for create / merge / delete / list.
 *
 * A workleaf is an ephemeral sub-worktree owned by a parent worktree
 * (or main). It runs its own Vite dev server on its own port, lives
 * under <repo-root>/workleafs/<parent>/workleaf--<slug>/, and gets
 * squash-merged back into its parent when `workleaf merge` is run.
 *
 * Usage:
 *   storyboard workleaf create <name>     Create + start dev server
 *   storyboard workleaf merge [name]      Squash into parent, then clean up
 *   storyboard workleaf delete [name]     Abandon without merging
 *   storyboard workleaf list              List all workleaves
 *   storyboard workleaf cd [name]         Print `cd <path>` for shell eval
 */

import * as p from '@clack/prompts'
import { existsSync } from 'node:fs'
import { resolve } from 'node:path'
import { repoRoot } from '../worktree/port.js'
import {
  detectWorkleafContext,
  workleafDir,
  listWorkleafs,
  parentOfWorkleaf,
} from '../workleaf/paths.js'
import { runCreate } from '../workleaf/create.js'
import { runMerge } from '../workleaf/merge.js'
import { runDelete } from '../workleaf/delete.js'
import { runList } from '../workleaf/list.js'
import { bold, dim, green, magenta, cyan } from './intro.js'

function helpScreen() {
  const cmd = (name, desc) => `    ${green(name.padEnd(36))}${desc}`
  const lines = [
    '',
    `  ${bold(magenta('storyboard workleaf'))}  ${dim('ephemeral sub-worktrees with their own dev server')}`,
    '',
    `  ${bold(cyan('Commands'))}`,
    cmd('workleaf create [name]', 'Create + start dev server (auto-name if omitted)'),
    cmd('workleaf create [name] --no-dev', 'Create without starting dev'),
    cmd('workleaf create [name] --no-install', 'Skip npm install'),
    cmd('workleaf merge [name]', 'Squash-merge into parent, then delete'),
    cmd('workleaf merge [name] --no-commit', 'Stage the squash but do not commit'),
    cmd('workleaf delete [name]', 'Abandon without merging (interactive)'),
    cmd('workleaf delete [name] --yes --force', 'Force-discard uncommitted work'),
    cmd('workleaf list', 'List all workleafs grouped by parent'),
    cmd('workleaf cd [name]', 'Print `cd <path>` for shell eval'),
    '',
    `  ${dim('Notes:')}`,
    `    ${dim('• Workleafs live at')} ${dim('<repo>/workleafs/<parent>/workleaf--<slug>/')}`,
    `    ${dim('• Branch name is')} ${dim('<parent>--workleaf--<slug>')}`,
    `    ${dim('• Workleafs cannot be nested')}`,
    '',
  ]
  console.log(lines.join('\n'))
}

/**
 * `workleaf cd` — print `cd <path>` to stdout so the user can
 *   eval "$(npx storyboard workleaf cd my-fix)"
 * Resolves the target by slug OR full branch name. Prints help text
 * to stderr so stdout stays parseable.
 */
function runCd(positionalName) {
  const root = repoRoot()

  let dir
  if (!positionalName) {
    const ctx = detectWorkleafContext()
    if (!ctx.inWorkleaf) {
      process.stderr.write('Pass a workleaf name or cd into one.\n')
      process.exit(1)
    }
    dir = ctx.dir
  } else {
    const branchInfo = parentOfWorkleaf(positionalName)
    if (branchInfo) {
      dir = workleafDir(branchInfo.parent, branchInfo.slug, root)
    } else {
      const matches = listWorkleafs(root).filter((w) => w.slug === positionalName)
      if (matches.length === 0) {
        process.stderr.write(`No workleaf named "${positionalName}" found.\n`)
        process.exit(1)
      }
      if (matches.length > 1) {
        process.stderr.write(`Multiple workleafs match "${positionalName}":\n`)
        for (const m of matches) process.stderr.write(`  ${m.branch}\n`)
        process.exit(1)
      }
      dir = matches[0].dir
    }
  }

  if (!existsSync(resolve(dir, '.git'))) {
    process.stderr.write(`Workleaf directory missing: ${dir}\n`)
    process.exit(1)
  }

  process.stdout.write(`cd ${JSON.stringify(dir)}\n`)
}

async function main() {
  const sub = process.argv[3]

  switch (sub) {
    case 'create':
      await runCreate()
      break
    case 'merge':
      await runMerge()
      break
    case 'delete':
    case 'rm':
      await runDelete()
      break
    case 'list':
    case 'ls':
      runList()
      break
    case 'cd':
      runCd(process.argv[4])
      break
    case undefined:
    case 'help':
    case '--help':
    case '-h':
      helpScreen()
      break
    default:
      helpScreen()
      p.log.error(`Unknown workleaf subcommand: ${bold(sub)}`)
      process.exit(1)
  }
}

main().catch((err) => {
  p.log.error(err.message || String(err))
  process.exit(1)
})
