#!/usr/bin/env node
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

import {
  REQUIRED_NODE_MAJOR,
  formatReleaseStamp,
  isReleaseExcluded,
  normalizeReleasePath,
  parseNodeMajor,
} from './student-release-utils.mjs'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(__dirname, '..')
const releaseDir = path.join(rootDir, 'release')

if (parseNodeMajor(process.version) < REQUIRED_NODE_MAJOR) {
  console.error(`Node.js ${process.version} 过低，需要 ${REQUIRED_NODE_MAJOR}+`)
  process.exit(1)
}

let JSZip
try {
  JSZip = (await import('jszip')).default
} catch {
  console.error('缺少 jszip 依赖。请先运行 npm install，然后重试 npm run package:student。')
  process.exit(1)
}

function walk(dir, files = []) {
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const abs = path.join(dir, entry.name)
    const rel = normalizeReleasePath(path.relative(rootDir, abs))
    if (isReleaseExcluded(rel)) continue
    if (entry.isDirectory()) {
      walk(abs, files)
    } else if (entry.isFile()) {
      files.push({ abs, rel })
    }
  }
  return files
}

const zip = new JSZip()
const files = walk(rootDir)
for (const file of files) {
  zip.file(file.rel, fs.readFileSync(file.abs))
}

const createdAt = new Date().toISOString()
zip.file('RELEASE-MANIFEST.txt', [
  'AIPROS Lite Student Release',
  `Created at: ${createdAt}`,
  '',
  'Start locally:',
  '  npm start',
  '',
  'Bundled Skill library:',
  '  184 complete Skills are imported and published automatically on first local start.',
  '',
  'Manual local runtime presets:',
  '  npm run runtime:setup -- qoder',
  '  npm run runtime:setup -- claude-code',
  '  npm run runtime:setup -- codebuddy',
  '  npm run runtime:setup -- trae',
  '',
  'Ask an AI coding tool to deploy:',
  '  Open AI-CODING-PROMPT.md and paste it into Cursor / Codex / Claude Code / Qoder.',
  '',
  'Cloudflare deploy:',
  '  npm run cloudflare:deploy',
  '',
  'Excluded from this package:',
  '  node_modules, dist, local env files, sqlite databases, uploads, .wrangler, SSL keys/certs, release output.',
  '',
].join('\n'))

fs.mkdirSync(releaseDir, { recursive: true })
const stamp = formatReleaseStamp(new Date(), process.env.AIPROS_RELEASE_TIME_ZONE || 'Asia/Shanghai')
const zipPath = path.join(releaseDir, `aipros-lite-student-release-${stamp}.zip`)
const buffer = await zip.generateAsync({
  type: 'nodebuffer',
  compression: 'DEFLATE',
  compressionOptions: { level: 9 },
})
fs.writeFileSync(zipPath, buffer)

console.log('学员 release 包已生成：')
console.log(zipPath)
console.log(`文件数：${files.length + 1}`)
console.log(`大小：${(buffer.length / 1024 / 1024).toFixed(2)} MB`)
