/**
 * Delete a workleaf without merging.
 *
 * Identical to `workleaf merge` minus the squash + commit steps. Used
 * to abandon a workleaf entirely — useful when an experiment didn't
 * pan out or when you want to free a port without preserving the work.
 *
 * Prompts for confirmation unless --yes is passed.
 */

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 './paths.js'
import { cleanupWorkleaf, hasDirtyWorkingTree } from './cleanup.js'
import { dim, bold, green, yellow } from '../cli/intro.js'
import { parseFlags } from '../cli/flags.js'

const flagSchema = {
  yes: { type: 'boolean', default: false, description: 'Skip interactive confirmation' },
  force: { type: 'boolean', default: false, description: 'Delete even if the workleaf has uncommitted changes' },
}

function resolveTarget(positionalName, root) {
  if (positionalName) {
    const branchInfo = parentOfWorkleaf(positionalName)
    if (branchInfo) {
      const dir = workleafDir(branchInfo.parent, branchInfo.slug, root)
      return { parent: branchInfo.parent, slug: branchInfo.slug, branch: positionalName, dir, root }
    }
    const matches = listWorkleafs(root).filter((w) => w.slug === positionalName)
    if (matches.length === 0) {
      p.log.error(`No workleaf named "${positionalName}" found.`)
      process.exit(1)
    }
    if (matches.length > 1) {
      p.log.error(`Multiple workleafs match "${positionalName}":`)
      for (const m of matches) console.log(`  ${m.branch}`)
      process.exit(1)
    }
    const m = matches[0]
    return { parent: m.parent, slug: m.slug, branch: m.branch, dir: m.dir, root }
  }
  const ctx = detectWorkleafContext()
  if (!ctx.inWorkleaf) {
    p.log.error('Not inside a workleaf — pass a name or cd into one.')
    p.log.info(`Usage: ${green('npx storyboard workleaf delete <name>')}`)
    process.exit(1)
  }
  return { parent: ctx.parent, slug: ctx.slug, branch: ctx.branch, dir: ctx.dir, root }
}

export async function runDelete(argv = process.argv.slice(4)) {
  const { flags, positional } = parseFlags(argv, flagSchema)
  const root = repoRoot()
  const target = resolveTarget(positional[0], root)
  const { branch, dir } = target

  p.intro('storyboard workleaf delete')
  p.log.info(`${dim('workleaf:')} ${bold(branch)}`)

  if (!existsSync(resolve(dir, '.git'))) {
    p.log.warn(`Workleaf directory missing: ${dim(dir)} — cleaning up registry anyway.`)
  } else if (hasDirtyWorkingTree(dir) && !flags.force) {
    p.log.error(`Workleaf has uncommitted changes — pass ${green('--force')} to discard them.`)
    process.exit(1)
  }

  if (!flags.yes) {
    const confirm = await p.confirm({
      message: `Permanently delete ${yellow(branch)}? This discards any unmerged commits.`,
      initialValue: false,
    })
    if (p.isCancel(confirm) || !confirm) {
      p.cancel('Cancelled')
      process.exit(0)
    }
  }

  // chdir out of the workleaf BEFORE cleanup so helpers that call
  // realpathSync(cwd) don't ENOENT when the dir is gone.
  try {
    const safeParent = target.parent === 'main' ? root : resolve(root, 'worktrees', target.parent)
    if (existsSync(safeParent)) process.chdir(safeParent)
    else process.chdir(root)
  } catch { /* cwd will stay where it is */ }

  p.log.step('Cleaning up workleaf')
  const { stopped } = cleanupWorkleaf({ branch, dir, root })

  p.note(
    [
      `  ${green('✓')} stopped ${stopped} dev server${stopped === 1 ? '' : 's'}`,
      `  ${green('✓')} removed ${dim(dir.replace(root + '/', ''))}`,
      `  ${green('✓')} deleted branch ${dim(branch)}`,
    ].join('\n'),
    `${bold(branch)} deleted`
  )
  p.outro('')
}
