import { resolveUserPath } from '@simon_he/vue-tui'
import { getProcessCwd, isNodeLike } from './runtime'

type RuntimeGlobals = typeof globalThis & {
  process?: Pick<NodeJS.Process, 'env'>
}

function runtimeGlobals(): RuntimeGlobals {
  return globalThis as RuntimeGlobals
}

function getHomeDir(): string {
  const env = runtimeGlobals().process?.env ?? {}
  const raw = String(env.HOME ?? env.USERPROFILE ?? '').trim()
  return raw.replace(/[\\/]+$/g, '')
}

export function tildifyPath(absPath: string): string {
  const p = String(absPath ?? '').trim()
  if (!p) return ''
  const home = getHomeDir()
  if (!home) return p
  if (p === home) return '~'
  if (p.startsWith(`${home}/`)) return `~${p.slice(home.length)}`
  if (p.startsWith(`${home}\\`)) return `~${p.slice(home.length)}`
  return p
}

export function formatCwdDisplay(cwd: unknown): string {
  const raw = String(cwd ?? '').trim()
  if (!raw) return ''
  if (!isNodeLike()) return raw
  const abs = resolveUserPath(getProcessCwd(), raw)
  return tildifyPath(abs)
}

const gitBranchInFlight = new Map<string, Promise<string>>()

export async function readGitBranch(cwd: unknown): Promise<string> {
  const abs = String(cwd ?? '').trim()
  if (!abs || !isNodeLike()) return ''
  const pending = gitBranchInFlight.get(abs)
  if (pending) return pending

  const task = (async () => {
    try {
      const { execFile } = await import('node:child_process')
      const { promisify } = await import('node:util')
      const execFileAsync = promisify(execFile)
      const { stdout } = await execFileAsync(
        'git',
        ['-C', abs, 'rev-parse', '--abbrev-ref', 'HEAD'],
        { timeout: 1200 },
      )
      const branch = String(stdout ?? '').trim()
      if (!branch || branch === 'HEAD') return ''
      return branch
    } catch {
      return ''
    }
  })()

  gitBranchInFlight.set(abs, task)
  const result = await task
  gitBranchInFlight.delete(abs)
  return result
}
