import * as git from '../lib/git.js'
import * as branch from '../lib/branch.js'
import * as config from '../lib/config.js'
import * as worktree from '../lib/worktree.js'
import type { CleanupResult, CleanupOptions } from './types.js'

export async function execute(
  opts: CleanupOptions,
  cwd?: string,
): Promise<CleanupResult> {
  try {
    // Must be on main or develop
    const currentBranch = await git.getCurrentBranch(cwd)
    const branchType = branch.detectBranchType(currentBranch)

    if (branchType !== 'main' && branchType !== 'develop') {
      return {
        success: false,
        analyzed: 0,
        permanent: 0,
        active: 0,
        deleted: [],
        skipped: [],
        error: `Must be on main or develop branch, currently on ${currentBranch}`,
      }
    }

    // Fetch all to get latest state
    await git.fetchAll(cwd)

    // Read config
    const cfg = await config.readConfigForPlatform()

    // List worktrees
    const wts = await worktree.listWorktrees(cwd)

    // Filter permanent worktrees (main, develop)
    const permanent = wts.filter((w) => {
      return w.branch === cfg.git.branches.main || w.branch === cfg.git.branches.develop
    }).length

    // Filter active worktrees (not merged)
    const active: typeof wts = []
    const merged: typeof wts = []

    for (const w of wts) {
      // Skip permanent
      if (w.branch === cfg.git.branches.main || w.branch === cfg.git.branches.develop) {
        continue
      }

      // Check if merged
      const isMerged = await git.isMerged(w.branch, cfg.git.branches.main, cwd)
      if (isMerged) {
        merged.push(w)
      } else {
        active.push(w)
      }
    }

    // Process merged worktrees
    const deleted: string[] = []
    const skipped: string[] = []

    for (const w of merged) {
      if (opts.force) {
        if (!opts.dryRun) {
          try {
            await worktree.removeWorktree(w.path, cwd)
            deleted.push(w.branch)
          } catch {
            skipped.push(`${w.branch} (cleanup failed)`)
          }
        } else {
          deleted.push(w.branch)
        }
      } else {
        skipped.push(`${w.branch} (not deleted: force flag not set)`)
      }
    }

    // Prune
    if (!opts.dryRun) {
      await git.execGit(['worktree', 'prune'], cwd)
    }

    return {
      success: true,
      analyzed: wts.length,
      permanent,
      active: active.length,
      deleted,
      skipped,
    }
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err)
    return {
      success: false,
      analyzed: 0,
      permanent: 0,
      active: 0,
      deleted: [],
      skipped: [],
      error: message,
    }
  }
}
