#!/usr/bin/env node
import { existsSync, mkdirSync, copyFileSync, writeFileSync, unlinkSync, readFileSync } from "fs"
import { join, dirname } from "path"
import { fileURLToPath } from "url"
import { homedir } from "os"
import { execSync } from "child_process"

const __dirname = dirname(fileURLToPath(import.meta.url))

// Only needed on Windows
if (process.platform !== "win32") {
  console.log("[muxcode postinstall] skipped (not Windows)")
  process.exit(0)
}

// Patch npm-generated wrappers to call bun directly, bypassing the
// node→spawnSync(bun) double-hop that breaks stdio inheritance on Windows.
try {
  const npmPrefix =
    process.env.npm_config_prefix ||
    execSync("npm config get prefix", { encoding: "utf8" }).trim()

  const bundle = join(__dirname, "dist", "index.js").replace(/\\/g, "\\\\")

  const ps1 = `#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$bun = Get-Command bun.cmd -ErrorAction SilentlyContinue
if (-not $bun) { $bun = Get-Command bun -ErrorAction SilentlyContinue }
if (-not $bun) { Write-Error "muxcode requires bun. Install: npm install -g bun"; exit 1 }
$bundle = Join-Path $basedir "node_modules\\@muxcodecli\\cli\\dist\\index.js"
if ($MyInvocation.ExpectingInput) {
  $input | & $bun.Source $bundle $args
} else {
  & $bun.Source $bundle $args
}
exit $LASTEXITCODE
`

  const cmd = `@ECHO off\r\nSETLOCAL\r\nSET "BUNDLE=%~dp0node_modules\\@muxcodecli\\cli\\dist\\index.js"\r\nbun "%BUNDLE%" %*\r\n`

  writeFileSync(join(npmPrefix, "muxcode.ps1"), ps1, "utf8")
  writeFileSync(join(npmPrefix, "muxcode.cmd"), cmd, "utf8")
  console.log("[muxcode postinstall] patched muxcode.ps1 and muxcode.cmd to call bun directly")
} catch (e) {
  console.warn("[muxcode postinstall] could not patch wrappers:", e.message)
}

const nativePkg = join(__dirname, "node_modules", "@opentui", "core-win32-x64")
const dllSrc = join(nativePkg, "opentui.dll")
const dest = join(process.env.APPDATA ?? homedir(), "muxcode", "opentui")
const dllCache = join(dest, "opentui.dll")

// Determine which DLL path to use
let targetDll = null

if (existsSync(dllSrc)) {
  // Fresh install — copy to cache for future updates
  targetDll = dllSrc
  try {
    mkdirSync(dest, { recursive: true })
    copyFileSync(dllSrc, dllCache)
    console.log("[muxcode postinstall] cached opentui.dll ->", dllCache)
  } catch (e) {
    console.warn("[muxcode postinstall] could not cache:", e.message)
  }
} else if (existsSync(dllCache)) {
  // Previous install already moved DLL to cache — use it
  targetDll = dllCache
  console.log("[muxcode postinstall] using cached opentui.dll")
} else {
  console.error("[muxcode postinstall] ERROR: opentui.dll not found in node_modules or cache")
  process.exit(0)
}

// Rewrite both index.js and index.bun.js to export the absolute DLL path
const newContent = `export default ${JSON.stringify(targetDll)}\n`
let okCount = 0

for (const f of ["index.bun.js", "index.js"]) {
  const p = join(nativePkg, f)
  if (!existsSync(p)) continue

  try {
    const current = readFileSync(p, "utf8")
    if (current.includes(targetDll)) {
      okCount++
      continue
    }
  } catch (_) {}

  try {
    // delete + recreate bypasses Windows read-only attribute
    try { unlinkSync(p) } catch (_) {}
    writeFileSync(p, newContent, "utf8")
    okCount++
    console.log("[muxcode postinstall] rewritten", f)
  } catch (e) {
    console.error("[muxcode postinstall] FAILED to rewrite", f, ":", e.message)
  }
}

if (okCount === 0) {
  console.error("[muxcode postinstall] WARNING: could not rewrite any index file — DLL may fail to load")
} else {
  console.log("[muxcode postinstall] done")
}
