#!/usr/bin/env node
import inquirer from 'inquirer'
import { execSync } from 'child_process'
import fs from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
import archiver from 'archiver'
import dayjs from 'dayjs'

// ---------- 环境配置 ----------
const ENV_CONFIG = {
  dev: { remoteUser: 'root', remoteIP: '192.168.2.140', remoteAppDir: '/work/web/dist' },
  test: { remoteUser: 'liujia', remoteIP: '43.137.10.199', remoteAppDir: '/work/web/dist' },
  prod: { remoteUser: 'root', remoteIP: '192.168.2.140', remoteAppDir: '/work/web/dist-prod' },
}
const SSH_PORT = 22
const LOCAL_DIST = 'D:/project/ln-web/dist'

// ---------- 处理环境参数 ----------
let env = process.argv[2] // npm run deploy:dev 传入 dev/test/prod
if (!env || !ENV_CONFIG[env]) {
  const answer = await inquirer.prompt([
    {
      type: 'list',
      name: 'env',
      message: '请选择要部署的环境：',
      choices: Object.keys(ENV_CONFIG),
      default: 'dev',
    },
  ])
  env = answer.env
}
const { remoteUser, remoteIP, remoteAppDir } = ENV_CONFIG[env]
console.log(`\n你选择的环境是: ${env}, 远程目录: ${remoteAppDir}\n`)

// ---------- 压缩 dist ----------
const timestamp = dayjs().format('YYYYMMDDHHmmss')
const zipFileName = `dist-${timestamp}.zip`
const zipPath = join(tmpdir(), zipFileName)

console.log('📦 正在压缩 dist...')
if (!fs.existsSync(LOCAL_DIST)) {
  console.error(`❌ 本地 dist 目录不存在: ${LOCAL_DIST}`)
  process.exit(1)
}

await new Promise((resolve, reject) => {
  const output = fs.createWriteStream(zipPath)
  const archive = archiver('zip', { zlib: { level: 9 } })
  output.on('close', () => resolve())
  archive.on('error', (err) => reject(err))
  archive.pipe(output)
  archive.directory(LOCAL_DIST, false)
  archive.finalize()
})

const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(2)
console.log(`✅ 压缩完成: ${zipSizeMB} MB, 文件: ${zipPath}`)

// ---------- 上传压缩包 ----------
const remoteZip = `/tmp/dist-latest-${timestamp}.zip`
execSync(`scp -P ${SSH_PORT} "${zipPath}" ${remoteUser}@${remoteIP}:${remoteZip}`, {
  stdio: 'inherit',
})

// ---------- 生成远程部署脚本 ----------
const useSudo = remoteUser !== 'root' ? 'sudo ' : ''
const remoteScriptContent = `#!/bin/bash
set -e
timestamp="${timestamp}"
tmpdir="/tmp/dist-temp-$timestamp"
target="${remoteAppDir}"
zipfile="${remoteZip}"

echo "📦 正在服务器上原子部署 ..."
echo "📁 创建临时目录 $tmpdir"
mkdir -p "$tmpdir"

echo "📦 解压上传文件"
unzip -qo "$zipfile" -d "$tmpdir"

echo "🔒 设置权限"
${useSudo}chown -R root:root "$tmpdir"

echo "🚀 替换新目录"
${useSudo}rm -rf "$target"
${useSudo}mv "$tmpdir" "$target"

echo "🧹 删除压缩包"
rm -f "$zipfile"

echo "✅ 远程部署完成: $target 更新成功"
`

const localScriptPath = join(tmpdir(), `deploy-temp-${timestamp}.sh`)
fs.writeFileSync(localScriptPath, remoteScriptContent, { encoding: 'utf8' })

// ---------- 上传远程脚本 ----------
const remoteScriptPath = `/tmp/deploy-temp-${timestamp}.sh`
execSync(`scp -P ${SSH_PORT} "${localScriptPath}" ${remoteUser}@${remoteIP}:${remoteScriptPath}`, {
  stdio: 'inherit',
})

// ---------- 执行远程脚本 ----------
console.log('\n🚀 执行远程部署脚本...')
try {
  execSync(
    `ssh -p ${SSH_PORT} ${remoteUser}@${remoteIP} "chmod +x ${remoteScriptPath} && bash ${remoteScriptPath}"`,
    {
      stdio: 'inherit',
    }
  )
} catch (err) {
  console.error('❌ 远程部署失败，请检查远程日志和权限', err)
  process.exit(1)
}

// ---------- 清理本地/远程临时文件 ----------
console.log('\n🧹 清理本地/远程临时文件...')
fs.unlinkSync(zipPath)
fs.unlinkSync(localScriptPath)
execSync(`ssh -p ${SSH_PORT} ${remoteUser}@${remoteIP} "rm -f ${remoteScriptPath} ${remoteZip}"`, {
  stdio: 'inherit',
})

console.log(`\n✅ [${env}] 环境部署完成！`)
