/**
 * 复制打包文件到服务器目录脚本
 * 功能：
 * 1. 检测服务器公共目录是否存在
 * 2. 检查目录权限
 * 3. 删除已存在的 web 目录
 * 4. 创建新的 web 目录
 * 5. 根据是否开启 SSR 实现不同的复制逻辑
 * 6. 复制打包文件到 web 目录
 */

const fs = require('fs');
const path = require('path');
const { loadEnv } = require('vite');

// 加载环境变量
const envData = loadEnv('production', path.resolve(__dirname, '..'));
const isSSR = !!envData.VITE_SSR;

// 路径定义
const projectRoot = path.resolve(__dirname, '..');
// 根据是否开启 SSR 设置不同的源目录
const distDir = isSSR ? projectRoot : path.join(projectRoot, '.output', 'public');
const serverPublicDir = path.resolve(projectRoot, '../server/public');
const serverWebDir = path.join(serverPublicDir, 'web');

// 文件过滤规则
const ssrFilters = ['.output', 'public', 'static', 'package.json', 'package-lock.json'];
const nonSsrFilters = [''];
const currentFilters = isSSR ? ssrFilters : nonSsrFilters;

/**
 * 检查路径是否符合过滤规则
 * @param {string} srcPath - 源文件路径
 * @returns {boolean} - 是否符合过滤规则
 */
function checkFilter(srcPath) {
  if (!isSSR) return true; // 非 SSR 模式复制所有文件
  if (srcPath === distDir) return true; // 根目录始终复制
  return currentFilters.some(filter => srcPath.includes(filter));
}

/**
 * 检查目录权限
 * @param {string} dirPath - 目录路径
 * @returns {boolean} - 是否有读写权限
 */
function checkPermission(dirPath) {
  try {
    fs.accessSync(dirPath, fs.constants.W_OK | fs.constants.R_OK);
    return true;
  } catch (error) {
    return false;
  }
}

/**
 * 递归删除目录
 * @param {string} dirPath - 目录路径
 */
function deleteDir(dirPath) {
  if (fs.existsSync(dirPath)) {
    fs.readdirSync(dirPath).forEach((file) => {
      const curPath = path.join(dirPath, file);
      if (fs.lstatSync(curPath).isDirectory()) {
        deleteDir(curPath);
      } else {
        fs.unlinkSync(curPath);
      }
    });
    fs.rmdirSync(dirPath);
  }
}

/**
 * 递归计算总文件数
 * @param {string} dirPath - 目录路径
 * @returns {number} - 总文件数
 */
function countTotalFiles(dirPath) {
  let count = 0;
  const files = fs.readdirSync(dirPath);
  files.forEach((file) => {
    const filePath = path.join(dirPath, file);
    if (fs.lstatSync(filePath).isDirectory()) {
      // 检查目录是否符合过滤规则
      if (checkFilter(filePath)) {
        count += countTotalFiles(filePath);
      }
    } else {
      // 检查文件是否符合过滤规则
      if (checkFilter(filePath)) {
        count++;
      }
    }
  });
  return count;
}

/**
 * 递归复制目录
 * @param {string} src - 源目录
 * @param {string} dest - 目标目录
 * @param {boolean} isRootDir - 是否为根目录
 * @param {number} totalFiles - 总文件数
 * @param {number} copiedFiles - 已复制文件数
 * @param {number} lastProgress - 上次显示的进度
 * @param {any} progressInterval - 进度检测定时器
 */
function copyDir(src, dest, isRootDir = true, totalFiles = 0, copiedFiles = 0, lastProgress = -1, progressInterval = null) {
  if (!fs.existsSync(dest)) {
    fs.mkdirSync(dest, { recursive: true });
  }
  if (isRootDir) {
    totalFiles = countTotalFiles(src);
    console.log(`开始复制，共 ${totalFiles} 个文件`);
    progressInterval = setInterval(() => {
      const progress = Math.round((copiedFiles / totalFiles) * 100);
      if (progress !== lastProgress) {
        console.log(`复制进度：${progress}% (${copiedFiles}/${totalFiles})`);
        lastProgress = progress;
      }
    }, 2000);
  }
  const files = fs.readdirSync(src);
  for (const file of files) {
    const srcPath = path.join(src, file);
    const destPath = path.join(dest, file);
    if (!checkFilter(srcPath)) {
      continue;
    }
    if (fs.lstatSync(srcPath).isDirectory()) {
      copiedFiles = copyDir(srcPath, destPath, false, totalFiles, copiedFiles, lastProgress, progressInterval);
    } else {
      fs.copyFileSync(srcPath, destPath);
      copiedFiles++;
    }
  }
  if (isRootDir && progressInterval) {
    clearInterval(progressInterval);
  }
  return copiedFiles;
}

console.log('====================================');
console.log('开始复制操作 ==> 📁 ', serverWebDir);
console.log('====================================');

// 检测服务器公共目录是否存在
if (!fs.existsSync(serverPublicDir)) {
  console.log('❌ 提示：../server/public 目录不存在，停止操作');
  process.exit(0);
}
// 检查服务器公共目录权限
if (!checkPermission(serverPublicDir)) {
  console.log('❌ 提示：没有 ../server/public 目录的读写权限，停止操作');
  process.exit(0);
}
// 检测并删除已存在的 web 目录
if (fs.existsSync(serverWebDir)) {
  try {
    if (!checkPermission(serverWebDir)) {
      console.log('❌ 提示：没有 ../server/public/web 目录的读写权限，停止操作');
      process.exit(0);
    }
    deleteDir(serverWebDir);
  } catch (error) {
    console.log('❌ 提示：删除 ../server/public/web 目录失败:', error.message);
    process.exit(0);
  }
}
// 确保目标目录存在
if (!fs.existsSync(serverWebDir)) {
  try {
    fs.mkdirSync(serverWebDir, { recursive: true });
  } catch (error) {
    console.log('❌ 提示：创建 ../server/public/web 目录失败:', error.message);
    process.exit(0);
  }
}
// 执行复制操作
try {
  if (!fs.existsSync(distDir)) {
    if (isSSR) {
      console.log('❌ 提示：项目根目录不存在，请先执行打包操作');
    } else {
      console.log('❌ 提示：.output/public 目录不存在，请先执行打包操作');
    }
    process.exit(0);
  }
  copyDir(distDir, serverWebDir);
} catch (error) {
  console.log('❌ 提示：文件复制失败:', error.message);
  process.exit(0);
}

console.log('\n====================================');
console.log('🎉 复制操作完成 ==> 📁 ', serverWebDir);
console.log('====================================');
