const express = require('express');
const mysql = require('mysql2/promise');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const cors = require('cors');
const crypto = require('crypto');
const fs = require('fs');  // 使用同步版本的 fs
const fsPromises = require('fs').promises;  // 使用 promises 版本的 fs
const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '.env') });
const CryptoJS = require('crypto-js');
const util = require('util');
const fileUpload = require('express-fileupload');

const app = express();

// 创建日志文件流
const logStream = fs.createWriteStream(path.join(__dirname, 'server.log'), { flags: 'a' });

// 创建管理员日志文件流
const adminLogStream = fs.createWriteStream(path.join(__dirname, 'admin.log'), { flags: 'a' });

// 自定义日志函数
function log(message) {
  const timestamp = new Date().toISOString();
  const logMessage = `${timestamp} - ${message}\n`;
  console.log(logMessage);
  logStream.write(logMessage);
}


// 允许所有源的 CORS 请求
app.use(cors());

app.use(express.json());
app.use(fileUpload({
  limits: { fileSize: 5 * 1024 * 1024 }, // 限制文件大小为5MB
  abortOnLimit: true
}));

// 创建数据库连接池
const pool = mysql.createPool({
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  charset: 'utf8mb4'
});

// 创建 SurveyKing 数据库连接池
const surveyKingPool = mysql.createPool({
  host: process.env.SurveyKing_DB_HOST,
  port: process.env.SurveyKing_DB_PORT,
  user: process.env.SurveyKing_DB_USER,
  password: process.env.SurveyKing_DB_PASSWORD,
  database: process.env.SurveyKing_DB_NAME,
  charset: 'utf8mb4'
});

// 在文件顶部的导入语句之后添加
pool.getConnection()
  .then(connection => {
    log('Successfully connected to the database.');
    connection.release();
  })
  .catch(err => {
    log(`Error connecting to the database: ${err}`);
  });

// 在文件顶部的导入语句之后添加
surveyKingPool.getConnection()
  .then(connection => {
    log('Successfully connected to the SurveyKing database.');
    connection.release();
  })
  .catch(err => {
    log(`Error connecting to the SurveyKing database: ${err}`);
  });


// 验证令牌的中间件
const authenticateToken = async (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) return res.sendStatus(401);

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [decoded.userId]);
    
    if (rows.length === 0 || new Date() > new Date(rows[0].expiration_date)) {
      return res.status(403).json({ error: '无效的令牌或账号已过期' });
    }

    // 检查token是否是最新的
    if (token !== rows[0].active_token) {
      return res.status(403).json({ error: '您的账号已在其他设备登录' });
    }

    req.user = rows[0];
    next();
  } catch (error) {
    return res.status(403).json({ error: '无效的令牌' });
  }
};

// 生成一个简单的密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
});

// 添加获取公钥的路由
app.get('/public-key', (req, res) => {
  res.json({ publicKey });
});


// 登录路由
app.post('/login', async (req, res) => {
  const { data, key, iv } = req.body;
  
  try {
    // 解密数据
    const decrypted = CryptoJS.AES.decrypt(
      data,
      CryptoJS.enc.Base64.parse(key),
      {
        iv: CryptoJS.enc.Base64.parse(iv),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      }
    );
    
    // 将解密后的数据转换为字符串
    const decryptedString = decrypted.toString(CryptoJS.enc.Utf8);
    
    // 解析 JSON 数据
    const { student_id_or_username, password } = JSON.parse(decryptedString);
    
    log(`Login attempt for: ${student_id_or_username}`);
    
    try {
      const [rows] = await pool.query('SELECT * FROM users WHERE username = ? OR student_id = ?', [student_id_or_username, student_id_or_username]);
      
      log(`Database query result: ${rows}`);
      
      if (rows.length === 0) {
        log('User not found');
        return res.status(401).json({ error: '用户名/邮箱或密码错误' });
      }
      
      const user = rows[0];
      
      if (new Date() > new Date(user.expiration_date)) {
        log(`Account expired for user: ${user.username}`);
        return res.status(403).json({ error: '账户已过期，请联系系统管理员xxx' });
      }
      
      const isPasswordValid = await bcrypt.compare(password, user.password);
      
      log(`Password validation result: ${isPasswordValid}`);
      
      if (!isPasswordValid) {
        log('Invalid password');
        return res.status(401).json({ error: '用户名/学号或密码错误' });
      }
      
      const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '24h' });
      
      // 更新用户的active_token
      await pool.query('UPDATE users SET active_token = ?, last_login = ? WHERE id = ?', [token, new Date(), user.id]);
      
      log(`Login successful for user: ${user.username}`);
      
      res.json({ 
        success: true, 
        username: user.username, 
        token,
        level: user.level,
        model:LICENSE_INFO.model
      });
    } catch (error) {
      log(`登录失败: ${error}`);
      res.status(500).json({ error: '登录失败', details: error.message });
    }
  } catch (error) {
    log(`登录解密失败: ${error}`);
    res.status(500).json({ 
      error: '登录失败',
      details: process.env.NODE_ENV === 'development' ? error.message : undefined 
    });
  }
});

// 登入路由
app.post('/logout', authenticateToken, (req, res) => {
  res.json({ success: true });
});

// 检认证状态
app.get('/check-auth', authenticateToken, async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [req.user.id]);
    if (rows.length === 0 || new Date() > new Date(rows[0].expiration_date)) {
      return res.status(403).json({ error: '账户已过期或无效' });
    }
    res.json({ 
      isAuthenticated: true,
      username: req.user.username,
      level: req.user.level,
      organization: req.user.organization,
    });
  } catch (error) {
    log(`检查认证状态失败: ${error}`);
    res.status(500).json({ error: '检查认证状态失败' });
  }
});

// 验证令牌
app.post('/verify-token', async (req, res) => {
  const { token } = req.body;

  if (!token) {
    return res.json({ valid: false });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    const [rows] = await pool.query('SELECT * FROM users WHERE id = ?', [decoded.userId]);
    
    if (rows.length === 0 || new Date() > new Date(rows[0].expiration_date)) {
      return res.json({ valid: false });
    }

    res.json({ valid: true, username: rows[0].username, level: rows[0].level });
  } catch (error) {
    res.json({ valid: false });
  }
});

// 修改获取用户信息路由
app.get('/user-info', authenticateToken, async (req, res) => {
  try {
    const [rows] = await pool.query(
      'SELECT username, class_name, student_id, organization, created_at, last_login, level FROM users WHERE id = ?', 
      [req.user.id]
    );
    
    if (rows.length > 0) {
      res.json({
        class_name: rows[0].class_name,
        username: rows[0].username,
        student_id: rows[0].student_id,
        organization: LICENSE_INFO.user,
        created_at: rows[0].created_at,
        last_login: rows[0].last_login,
        level: rows[0].level,
        model:LICENSE_INFO.model
      });
    } else {
      res.status(404).json({ error: '用户不存在' });
    }
  } catch (error) {
    log(`获取用户信息失败: ${error}`);
    res.status(500).json({ error: '获取用户信息失败' });
  }
});

// 验证管理员权限
app.get('/verify-admin', authenticateToken, async (req, res) => {
  try {
    const [rows] = await pool.query('SELECT level FROM users WHERE id = ?', [req.user.id]);
    if (rows.length > 0 && rows[0].level >= 7) {
      res.json({ isAdmin: true });
    } else {
      res.json({ isAdmin: false });
    }
  } catch (error) {
    log(`验证管理员权限失败: ${error}`);
    res.status(500).json({ error: '验证管理员权限失败' });
  }
});

// 查询用户
app.get('/admin/users', authenticateToken, async (req, res) => {
  try {
    const [userRows] = await pool.query('SELECT level FROM users WHERE id = ?', [req.user.id]);
    if (userRows.length === 0 || userRows[0].level < 7) {
      return res.status(403).json({ error: '没有权限访问此资源' });
    }

    const [rows] = await pool.query(
      'SELECT id, username, student_id, class_name, organization, created_at, last_login, level FROM users'
    );
    res.json(rows);
  } catch (error) {
    log(`获取用户列表失败: ${error}`);
    res.status(500).json({ error: '获取用户列表失败' });
  }
});

// 批量创建用户
app.post('/admin/users', authenticateToken, async (req, res) => {
  try {
    // 权限校验：仅管理员(level >= 3)可执行
    const [adminCheck] = await pool.query('SELECT level FROM users WHERE id = ?', [req.user.id]);
    if (adminCheck.length === 0 || adminCheck[0].level < 7) {
      return res.status(403).json({ success: false, error: '没有权限执行此操作' });
    }

    const { class_name, student_ids } = req.body;
    if (!class_name || !student_ids) {
      return res.status(400).json({ success: false, error: '请提供班级和学号' });
    }

    // 支持多种分隔符：空格、英文逗号、中文逗号、换行
    const idList = student_ids
      .split(/[\s,，\n]+/)
      .map(id => id.trim())
      .filter(id => id.length > 0);

    if (idList.length === 0) {
      return res.status(400).json({ success: false, error: '未检测到有效学号' });
    }

    // 根据LICENSE_INFO.model确定最大用户数量
    let maxUsers = 0; // 默认值
    const licenseModel = LICENSE_INFO.model || '';
    
    if (licenseModel.includes('EST-05E')) {
      maxUsers = 10;
    } else if (licenseModel.includes('EST-10E')) {
      maxUsers = 60;
    } else if (licenseModel.includes('EST-100E')) {
      maxUsers = 100;
    } else if (licenseModel.includes('EST-05C')) {
      maxUsers = 10;
    } else if (licenseModel.includes('EST-10C')) {
      maxUsers = 60;
    } else if (licenseModel.includes('EST-100C')) {
      maxUsers = 100;
    } else if (licenseModel.includes('EST-10A')) {
      maxUsers = 60;
    } else if (licenseModel.includes('EST-100A')) {
      maxUsers = 100;
    }else if (licenseModel.includes('EST-100D')) {
      maxUsers = 100;
    }

    // 检查当前用户数量
    const [currentUsers] = await pool.query('SELECT COUNT(*) as count FROM users');
    const currentUserCount = currentUsers[0].count -1;
    
    // 计算可以创建的最大新用户数量
    const maxNewUsers = maxUsers - currentUserCount;
    
    // 如果新用户数量超过限制，返回错误
    if (idList.length > maxNewUsers) {
      return res.status(400).json({ 
        success: false, 
        error: `超出许可证用户数量限制，当前许可证(${licenseModel})最多允许${maxUsers}个用户，已有${currentUserCount}个用户，最多可创建${maxNewUsers}个新用户` 
      });
    }

    let createdCount = 0;
    let skipped = [];

    for (const sid of idList) {
      // 检查是否已存在
      const [exists] = await pool.query('SELECT id FROM users WHERE student_id = ?', [sid]);
      if (exists.length > 0) {
        skipped.push(sid);
        continue;
      }

      const plainPassword = sid;
      const password = await bcrypt.hash(plainPassword, 10); // saltRounds = 10

      const organization = LICENSE_INFO.user;
      const level = 0

      await pool.query(
        `INSERT INTO users (username, student_id, class_name, organization, level, password, created_at)
         VALUES (?, ?, ?, ?, ?, ?, NOW())`,
        [sid, sid, class_name, organization, level, password]
      );

      createdCount++;
    }

    res.json({
      success: true,
      createdCount,
      skipped,
      message: `成功创建 ${createdCount} 个用户，跳过 ${skipped.length} 个已存在的用户`,
      licenseInfo: {
        model: licenseModel,
        maxUsers: maxUsers,
        currentUsers: currentUserCount + createdCount,
        remainingSlots: maxUsers - (currentUserCount + createdCount)
      }
    });

  } catch (error) {
    console.error('批量创建用户失败:', error);
    res.status(500).json({ success: false, error: '批量创建用户失败', details: error.message });
  }
});

// 删除用户
app.delete('/admin/users/:student_id', authenticateToken, async (req, res) => {
  try {
    const [adminCheck] = await pool.query('SELECT level FROM users WHERE id = ?', [req.user.id]);
    if (adminCheck.length === 0 || adminCheck[0].level < 7) {
      return res.status(403).json({ success: false, error: '没有权限执行此操作' });
    }

    const studentId = req.params.student_id;
    const [result] = await pool.query('DELETE FROM users WHERE student_id = ?', [studentId]);
    if (result.affectedRows === 0) {
      return res.status(404).json({ success: false, error: '未找到该用户' });
    }

    res.json({ success: true, message: `已删除用户 ${studentId}` });
  } catch (error) {
    console.error('删除用户失败:', error);
    res.status(500).json({ success: false, error: '删除用户失败' });
  }
});


let onlineUsers = new Map();
let onlineHistory = [];

const ONLINE_DATA_FILE = path.join(__dirname, 'online_data.json');
const LONG_TERM_HISTORY_FILE = path.join(__dirname, 'long_term_history.json');

// 加载在线用户数据
async function loadOnlineData() {
  try {
    const data = await fsPromises.readFile(ONLINE_DATA_FILE, 'utf8');
    const parsedData = JSON.parse(data);
    onlineHistory = parsedData.history;
    onlineUsers = new Map(parsedData.users.map(([id, user]) => [parseInt(id), user]));
  } catch (error) {
    if (error.code !== 'ENOENT') {
      console.error('加载在线用户数据失败:', error);
    }
  }
}

// 保存在线用户数据
async function saveOnlineData() {
  try {
    const data = JSON.stringify({
      history: onlineHistory,
      users: Array.from(onlineUsers.entries())
    });
    await fsPromises.writeFile(ONLINE_DATA_FILE, data, 'utf8');
  } catch (error) {
    console.error('保存在线用户数据失败:', error);
  }
}


// 更新在线用户并记录历史
async function updateOnlineUsers() {
  const now = new Date();
  // 清理超时的用户（例如，15分钟无活动）
  for (const [userId, userData] of onlineUsers.entries()) {
    if (now - new Date(userData.lastActivity) > 5 * 60 * 1000) {
      onlineUsers.delete(userId);
    }
  }

  const currentOnlineUsers = {
    time: now.toISOString(),
    count: onlineUsers.size,
    users: Array.from(onlineUsers.values()).map(u => u.username)
  };

  onlineHistory.push(currentOnlineUsers);

  // 将超过24小时的记录移动到长期历史记录
  const oneDayAgo = new Date(now - 24 * 60 * 60 * 1000);
  const oldRecords = onlineHistory.filter(item => new Date(item.time) <= oneDayAgo);
  onlineHistory = onlineHistory.filter(item => new Date(item.time) > oneDayAgo);


  await saveOnlineData();
}

// 每10秒更新一次在线用户状态
setInterval(updateOnlineUsers, 10000);

// 在服务器启动时加载在线用户数据
loadOnlineData().then(() => {
  console.log('在线用户数据加载完成');
});

// 登录路由
app.post('/login', async (req, res) => {
  // ... 现有的登录逻辑 ...

  if (response.data.success) {
    // 添加用户到在线列表
    onlineUsers.set(user.id, {
      username: user.username,
      lastActivity: new Date().toISOString()
    });
    await saveOnlineData();
  }

  res.json({ success: true });
});

// 获取在线用户和历史记录
app.get('/online-users', authenticateToken, (req, res) => {
  res.json({
    currentOnline: {
      count: onlineUsers.size,
      users: Array.from(onlineUsers.values()).map(u => u.username)
    },
    history: onlineHistory
  });
});

// 更新用户活动时间
app.post('/update-activity', authenticateToken, async (req, res) => {
  if (onlineUsers.has(req.user.id)) {
    onlineUsers.get(req.user.id).lastActivity = new Date().toISOString();
  } else {
    onlineUsers.set(req.user.id, {
      username: req.user.username,
      lastActivity: new Date().toISOString()
    });
  }
  await saveOnlineData();
  res.sendStatus(200);
});

// 登出路由
app.post('/logout', authenticateToken, async (req, res) => {
  onlineUsers.delete(req.user.id);
  await saveOnlineData();
  res.json({ success: true });
});



// --------------------------LIC验证-------------------
// 全局许可证信息
const LICENSE_INFO = {
  isValid: false,
  model: "",
  user: "",
  serial: "",
  activation_code: "",
  activated_at: "",
  expires_at: "",
  gold_service_expires_at: "",
  issued_at: "",
  issuer: "",
  hardware_id: "" // 新增硬件码字段
};

// 获取系统硬件序列号
async function getHardwareSerial() {
  try {
    const hardwareSerial = await fsPromises.readFile('/hardware_serial', 'utf8');
    return hardwareSerial.trim();
  } catch (error) {
    log(`读取硬件序列号失败: ${error.message}`);
    throw error;
  }
}

// License 验证相关功能
// 获取目录下所有 .lic 文件
async function getLicenseFiles() {
  try {
    const licenseDir = path.join(__dirname, 'license');
    const files = await fsPromises.readdir(licenseDir);
    return files.filter(file => file.endsWith('.lic'));
  } catch (error) {
    if (error.code === 'ENOENT') {
      // 如果目录不存在，返回空数组
      return [];
    }
    log(`获取 License 文件失败: ${error.message}`);
    throw error;
  }
}

// 清空 LICENSE_INFO
function clearLicenseInfo() {
  Object.keys(LICENSE_INFO).forEach(key => {
    LICENSE_INFO[key] = typeof LICENSE_INFO[key] === 'boolean' ? false : "";
  });
}

// 读取公钥文件
async function readPublicKey() {
  try {
    const pubKeyPath = path.join(__dirname, 'pub.pem');
    const publicKeyData = await fsPromises.readFile(pubKeyPath, 'utf8');
    return publicKeyData;
  } catch (error) {
    log(`读取公钥文件失败: ${error.message}`);
    throw error;
  }
}

// 验证 License 文件
async function verifyLicense(licenseFile, publicKey) {
  try {
    const licenseDir = path.join(__dirname, 'license');
    const licenseData = await fsPromises.readFile(path.join(licenseDir, licenseFile), 'utf8');
    const license = JSON.parse(licenseData);
    
    // 解码 payload
    const payloadStr = Buffer.from(license.payload, 'base64').toString('utf8');
    const payload = JSON.parse(payloadStr);
    
    // 验证签名
    const verify = crypto.createVerify('SHA256');
    verify.update(payloadStr);
    const isValid = verify.verify(publicKey, license.signature, 'base64');

    // 验证硬件码匹配
    const hardwareSerial = await getHardwareSerial();
    const hardwareMatches = payload.hardware_id === hardwareSerial;
    
    // 只有在签名验证成功且硬件码匹配时才更新许可证信息
    if (isValid && hardwareMatches) {
      LICENSE_INFO.isValid = true;
      LICENSE_INFO.model = payload.model || "";
      LICENSE_INFO.user = payload.user || "";
      LICENSE_INFO.serial = payload.serial || "";
      LICENSE_INFO.activation_code = payload.activation_code || "";
      LICENSE_INFO.activated_at = payload.activated_at || "";
      LICENSE_INFO.expires_at = payload.expires_at || "";
      LICENSE_INFO.gold_service_expires_at = payload.gold_service_expires_at || "";
      LICENSE_INFO.issued_at = payload.issued_at || "";
      LICENSE_INFO.issuer = payload.issuer || "";
      LICENSE_INFO.hardware_id = payload.hardware_id || "";
    } else {
      clearLicenseInfo();
    }
    
    return {
      isValid,
      hardwareMatches,
      licenseFile,
      payload
    };
  } catch (error) {
    log(`验证 License 文件失败 (${licenseFile}): ${error.message}`);
    clearLicenseInfo();
    return {
      isValid: false,
      hardwareMatches: false,
      licenseFile,
      error: error.message
    };
  }
}

// 验证所有 License 文件
async function verifyAllLicenses() {
  try {
    const licenseFiles = await getLicenseFiles();
    if (licenseFiles.length === 0) {
      log('未找到任何 License 文件');
      clearLicenseInfo();
      return [];
    }
    
    // 只验证最新的 license 文件
    const latestLicenseFile = licenseFiles[licenseFiles.length - 1];
    log(`验证最新的 License 文件: ${latestLicenseFile}`);
    
    try {
      const publicKey = await readPublicKey();
      log('成功读取公钥文件 pub.pem');
      
      const result = await verifyLicense(latestLicenseFile, publicKey);
      
      // 输出验证结果
      if (result.isValid && result.hardwareMatches) {
        log(`License 验证成功: ${latestLicenseFile}`);
        log(`License 信息: ${JSON.stringify(result.payload, null, 2)}`);
      } else {
        log(`License 验证失败: ${latestLicenseFile}`);
        if (!result.isValid) {
          log('签名验证失败');
        }
        if (!result.hardwareMatches) {
          log('硬件码不匹配');
        }
        if (result.error) {
          log(`错误信息: ${result.error}`);
        }
        clearLicenseInfo();
      }
      
      return [result];
    } catch (error) {
      log(`读取公钥失败: ${error.message}`);
      clearLicenseInfo();
      return [{
        isValid: false,
        hardwareMatches: false,
        licenseFile: latestLicenseFile,
        error: '无法读取公钥文件'
      }];
    }
  } catch (error) {
    log(`验证所有 License 文件失败: ${error.message}`);
    clearLicenseInfo();
    throw error;
  }
}

// 获取许可证信息
function getLicenseInfo() {
  return LICENSE_INFO;
}

// 添加获取许可证信息的API端点
app.get('/license-info', authenticateToken, (req, res) => {
  res.json({
    success: true,
    licenseInfo: LICENSE_INFO
  });
});

// 添加获取产品型号的API端点
app.get('/product-model', (req, res) => {
  res.json({
    success: true,
    isValid: LICENSE_INFO.isValid,
    model: LICENSE_INFO.model
  });
});

// 添加上传许可证文件的API端点
app.post('/upload-license', async (req, res) => {
  if (!req.files || Object.keys(req.files).length === 0) {
    return res.status(400).json({ success: false, error: '未上传文件' });
  }

  const licenseFile = req.files.license;
  
  // 验证文件扩展名
  if (!licenseFile.name.endsWith('.lic')) {
    return res.status(400).json({ success: false, error: '文件必须是.lic格式' });
  }

  try {
    // 验证硬件码匹配
    const hardwareSerial = await getHardwareSerial();
    
    // 读取并解析上传的 license 文件内容
    const licenseContent = licenseFile.data.toString('utf8');
    const license = JSON.parse(licenseContent);
    const payloadStr = Buffer.from(license.payload, 'base64').toString('utf8');
    const payload = JSON.parse(payloadStr);
    
    // 检查硬件码是否匹配
    if (payload.hardware_id !== hardwareSerial) {
      return res.status(400).json({ 
        success: false,
        error: '硬件码不匹配，无法使用此许可证' 
      });
    }

    // 确保 license 目录存在
    const licenseDir = path.join(__dirname, 'license');
    await fsPromises.mkdir(licenseDir, { recursive: true });
    
    // 删除现有的所有 license 文件
    const existingFiles = await getLicenseFiles();
    for (const file of existingFiles) {
      await fsPromises.unlink(path.join(licenseDir, file));
      log(`删除旧的许可证文件: ${file}`);
    }
    
    // 保存新的 license 文件
    await licenseFile.mv(path.join(licenseDir, licenseFile.name));
    log(`新的许可证文件 ${licenseFile.name} 上传成功到 license 目录`);
    
    // 重新验证许可证
    await verifyAllLicenses();
    
    res.json({
      success: true,
      message: '许可证文件上传并验证成功',
      licenseInfo: LICENSE_INFO
    });
  } catch (error) {
    log(`许可证文件上传失败: ${error.message}`);
    res.status(500).json({ success: false, error: '许可证文件上传失败' });
  }
});

// 检查许可证状态的API端点
app.get('/license-status', (req, res) => {
  res.json({
    success: true,
    isValid: LICENSE_INFO.isValid
  });
});

// 监视 license 目录变化
const licenseDir = path.join(__dirname, 'license');
fs.mkdir(licenseDir, { recursive: true }, (err) => {
  if (err) {
    log(`创建 license 目录失败: ${err.message}`);
    return;
  }
  
  fs.watch(licenseDir, async (eventType, filename) => {
    if (filename && filename.endsWith('.lic')) {
      log(`检测到 license 目录变化: ${eventType} - ${filename}`);
      try {
        await verifyAllLicenses();
      } catch (error) {
        log(`处理 license 目录变化时发生错误: ${error.message}`);
      }
    }
  });
});

// 在服务器启动时验证 License 文件
(async function checkLicensesOnStartup() {
  log('正在验证 License 文件...');
  try {
    await verifyAllLicenses();
    log('License 验证完成');
  } catch (error) {
    log(`License 验证过程中发生错误: ${error.message}`);
  }
})();

// ---------------------------------------------------------------

// -----------------添加查询 SurveyKing 答案数据的接口----------
app.get('/survey-answers', async (req, res) => {
  try {
    const { org } = req.query;
    
    if (!org) {
      return res.status(400).json({
        success: false,
        error: '请提供组织名称参数 (org)'
      });
    }

    // 基础查询
    const query = `
      SELECT 
        project_id,
        answer,
        exam_score,
        update_at
      FROM t_answer 
      WHERE 1=1
    `;

    // 执行查询
    const [rows] = await surveyKingPool.query(query);

    // 处理结果，解析 answer 列中的 JSON 数据并只返回匹配组织的数据
    const processedData = rows.map(row => {
      try {
        const answerData = JSON.parse(row.answer);
        
        // 查找包含 estorg 的键
        let organization = '';
        let username = '';
        
        // 遍历对象查找 estorg
        for (const key in answerData) {
          if (answerData[key].estorg) {
            organization = answerData[key].estorg;
          }
          if (answerData[key].estuser) {
            username = answerData[key].estuser;
          }
        }

        // 只返回匹配组织的数据
        if (organization && organization.toLowerCase() === org.toLowerCase()) {
          return {
            projectId: row.project_id,
            organization: organization,
            username: username,
            score: row.exam_score,
            submitTime: row.update_at
          };
        }
        return null;
      } catch (error) {
        console.error(`解析答案数据失败: ${error}`);
        return null;
      }
    }).filter(item => item !== null); // 移除不匹配的数据

    // 按提交时间降序排序
    processedData.sort((a, b) => new Date(b.submitTime) - new Date(a.submitTime));

    res.json({
      success: true,
      total: processedData.length,
      data: processedData
    });

  } catch (error) {
    console.error(`获取答案数据失败: ${error}`);
    res.status(500).json({ 
      success: false, 
      error: '获取答案数据失败',
      message: error.message 
    });
  }
});
// --------------------------------------------------

// -----------场景化功能切换API-----------------------
app.post('/admin/toggle-scenario', authenticateToken, async (req, res) => {
  try {
    // 验证管理员权限
    const [adminCheck] = await pool.query('SELECT level FROM users WHERE id = ?', [req.user.id]);
    if (adminCheck.length === 0 || adminCheck[0].level < 7) {
      return res.status(403).json({ 
        success: false, 
        message: '没有权限执行此操作' 
      });
    }

    const { student_id, new_level } = req.body;
    
    // 如果是要关闭场景化功能，直接执行
    if (new_level === 0) {
      const [updateResult] = await pool.query(
        'UPDATE users SET level = ? WHERE student_id = ?', 
        [0, student_id]
      );
      
      if (updateResult.affectedRows === 0) {
        return res.status(404).json({ 
          success: false, 
          message: '未找到该用户' 
        });
      }
      
      return res.json({ 
        success: true, 
        message: '已关闭场景化功能', 
        new_level: 0 
      });
    }
    
    // 如果是要开启场景化功能，需要检查许可证和当前已开启的用户数量
    // 根据LICENSE_INFO.model确定最大用户数
    let maxScenarioUsers = 0;
    const model = LICENSE_INFO.model;
    
    switch (model) {
      case 'EST-05E':
        maxScenarioUsers = 5;
        break;
      case 'EST-10E':
        maxScenarioUsers = 30;
        break;
      case 'EST-100E':
        maxScenarioUsers = 50;
        break;
      case 'EST-05C':
        maxScenarioUsers = 5;
        break;
      case 'EST-10C':
        maxScenarioUsers = 30;
        break;
      case 'EST-100C':
        maxScenarioUsers = 50;
        break;
      case 'EST-10A':
        maxScenarioUsers = 30;
        break;
      case 'EST-100A':
        maxScenarioUsers = 50;
        break;
      case 'EST-100D':
        maxScenarioUsers = 50;
        break;
      default:
        maxScenarioUsers = 0;
    }
    
    // 如果没有有效的许可证或型号不支持
    if (!LICENSE_INFO.isValid || maxScenarioUsers === 0) {
      return res.status(403).json({ 
        success: false, 
        message: '无有效许可证或当前型号不支持场景化功能' 
      });
    }
    
    // 查询当前已开启场景化功能的用户数量（level=1或level=4）
    const [countResult] = await pool.query(
      'SELECT COUNT(*) as count FROM users WHERE level = 1 OR level = 4'
    );
    
    const currentCount = countResult[0].count;
    
    // 如果当前数量已达到最大值，拒绝请求
    if (currentCount >= maxScenarioUsers) {
      return res.status(403).json({ 
        success: false, 
        message: `已达到最大场景化用户数量限制${maxScenarioUsers}位用户` 
      });
    }
    
    // 更新用户等级为1（开启场景化功能）
    const [updateResult] = await pool.query(
      'UPDATE users SET level = ? WHERE student_id = ?', 
      [1, student_id]
    );
    
    if (updateResult.affectedRows === 0) {
      return res.status(404).json({ 
        success: false, 
        message: '未找到该用户' 
      });
    }
    
    return res.json({ 
      success: true, 
      message: '已开启场景化功能', 
      new_level: 1 
    });
    
  } catch (error) {
    console.error('切换场景化功能失败:', error);
    res.status(500).json({ 
      success: false, 
      message: '操作失败，请稍后再试', 
      error: error.message 
    });
  }
});

// ---------------------------------------------------



// ---------------------宿主机网络配置----------------------------
// 网络配置相关 API
const NETWORK_CONFIG_FILE = path.join(__dirname, 'network');

// 读取网络配置
async function readNetworkConfig() {
  try {
    const config = await fsPromises.readFile(NETWORK_CONFIG_FILE, 'utf8');
    const configObj = {};
    config.split('\n').forEach(line => {
      const [key, value] = line.split('=').map(part => part.trim());
      if (key && value) {
        // 移除引号
        configObj[key] = value.replace(/^"(.*)"$/, '$1');
      }
    });
    return configObj;
  } catch (error) {
    log(`读取网络配置失败: ${error.message}`);
    throw error;
  }
}

// 写入网络配置
async function writeNetworkConfig(config) {
  try {
    let configContent = '';
    for (const [key, value] of Object.entries(config)) {
      // DNS 需要特殊处理，添加引号
      if (key === 'DNS') {
        configContent += `${key}="${value}"\n`;
      } else {
        configContent += `${key}=${value}\n`;
      }
    }
    await fsPromises.writeFile(NETWORK_CONFIG_FILE, configContent);
  } catch (error) {
    log(`写入网络配置失败: ${error.message}`);
    throw error;
  }
}

// 获取网络配置 API
app.get('/network-config', authenticateToken, async (req, res) => {
  try {
    const config = await readNetworkConfig();
    res.json({
      success: true,
      config
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: '获取网络配置失败'
    });
  }
});

// 更新网络配置 API
app.post('/network-config', authenticateToken, async (req, res) => {
  try {
    const { config } = req.body;
    
    // 基本验证
    if (!config || typeof config !== 'object') {
      return res.status(400).json({
        success: false,
        error: '无效的配置数据'
      });
    }

    if (!config.BOOTPROTO) {
      return res.status(400).json({
        success: false,
        error: '缺少必需字段: BOOTPROTO'
      });
    }
    // 限定 BOOTPROTO 的取值
    if (!['dhcp', 'static'].includes(config.BOOTPROTO)) {
      return res.status(400).json({
        success: false,
        error: 'BOOTPROTO 仅支持 dhcp 或 static'
      });
    }

    // 如果是静态 IP，验证额外字段
    if (config.BOOTPROTO === 'static') {
      const staticFields = ['IPADDR', 'NETMASK', 'GATEWAY', 'DNS'];
      for (const field of staticFields) {
        if (!config[field]) {
          return res.status(400).json({
            success: false,
            error: `静态 IP 配置缺少必需字段: ${field}`
          });
        }
      }
    }

    const existingConfig = await readNetworkConfig();
    const allowedUpdateKeys = ['BOOTPROTO', 'IPADDR', 'NETMASK', 'GATEWAY', 'DNS'];
    const updatedConfig = { ...existingConfig };
    for (const key of allowedUpdateKeys) {
      if (config[key] !== undefined) {
        updatedConfig[key] = config[key];
      }
    }

    if (config.BOOTPROTO === 'dhcp') {
      for (const key of ['IPADDR', 'NETMASK', 'GATEWAY', 'DNS']) {
        delete updatedConfig[key];
      }
    }

    await writeNetworkConfig(updatedConfig);
    res.json({
      success: true,
      message: '网络配置已更新'
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: '更新网络配置失败'
    });
  }
});

// ------------------------------------------------------

// -------------------------API启动设置-----------------
const PORT = process.env.PORT || 3000;
// 如果作为主模块运行（独立启动），才开启监听；作为子服务被挂载时不监听端口
if (require.main === module) {
  const PORT = process.env.PORT || 3000;
  app.listen(PORT, () => {
    log(`Server running on port ${PORT}`);
  });
}

// 导出 Express 应用，供主入口统一挂载
module.exports = app;

// 在程序退出时关闭日志流
process.on('exit', () => {
  logStream.end();
});

// 捕获未捕获的异常并记录日志
process.on('uncaughtException', (error) => {
  log(`Uncaught Exception: ${error.message}`);
  process.exit(1);
});

// 捕获未处理的 Promise 拒绝并记录日志
process.on('unhandledRejection', (reason, promise) => {
  log(`Unhandled Rejection at: ${promise}, reason: ${reason}`);
});
