const express = require('express');
const cors = require('cors');
const fs = require('fs');
const path = require('path');

const app = express();

// 初始连接映射数据
const initialConnectionMap = {
  pass: {
    //---Copper连接检查--- 
    "main-permanent": {
      type: "copper",
      connectedTo: "remote-channel",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "remote-channel": {
      type: "copper",
      connectedTo: "main-channel",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "main-channel": {
      type: "copper",
      connectedTo: "remote-permanent",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
  //---CFP连接检查--- 
    "main-cfp-sm-out": {
      type: "fiber",
      connectedTo: "remote-cfp-in",
      fiberstatus: "ref-pass"
    },
    "main-cfp-mm-out": {
      type: "fiber",
      connectedTo: "remote-cfp-in",
      fiberstatus: "ref-pass"
    },

    "remote-cfp-sm-out": {
      type: "fiber",
      connectedTo: "main-cfp-in",
      fiberstatus: "ref-pass"
    },
    "remote-cfp-mm-out": {
      type: "fiber",
      connectedTo: "main-cfp-in",
      fiberstatus: "ref-pass"
    },

  },
  Office: {
    "Room1-TO-1": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-1",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Room1-TO-2": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-2",
      wiremapstatus: "open",
      performancestatus: "pass"
    },
    "Room2-TO-1": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-3",
      wiremapstatus: "short",
      performancestatus: "pass"
    },
    "Room2-TO-2": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-4",
      wiremapstatus: "cross",
      performancestatus: "pass"
    },
    "Room3-TO-1": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-5",
      wiremapstatus: "reversed",
      performancestatus: "pass"
    },
    "Room3-TO-2": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-6",
      wiremapstatus: "miswire",
      performancestatus: "pass"
    },
    "Room4-CAM": {
      type: "copper",
      apitype:"t568b",
      connectedTo: "Rack1-1A-7",
      wiremapstatus: "pass",
      performancestatus: "return-loss-fail"
    },
    "Rack1-1B-1": {
      type: "fiber",
      apitype:"otdr",
      connectedTo: "Rack1-1B-5",
      fiberstatus: "sm-pass"
    },
    "Rack1-1B-2": {
      type: "fiber",
      apitype:"otdr",
      connectedTo: "Rack1-1B-6",
      fiberstatus: "connector-fail-start"
    },
    "Rack1-1B-3": {
      type: "fiber",
      apitype:"otdr",
      connectedTo: "Rack1-1B-7",
      fiberstatus: "splice-fail"
    },
    "Rack1-1B-4": {
      type: "fiber",
      apitype:"otdr",
      connectedTo: "Rack1-1B-8",
      fiberstatus: "bend"
    }
  },
  Industry: {
    "Device1-1": {
      type: "copper",
      apitype:"workshop-m12",
      connectedTo: "Cabinet-A1",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device1-2": {
      type: "copper",
      apitype:"workshop-m12",
      connectedTo: "Cabinet-A2",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device2-1": {
      type: "copper",
      apitype:"workshop-m12",
      connectedTo: "Cabinet-A3",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device2-2": {
      type: "copper",
      apitype:"workshop-m12",
      connectedTo: "Cabinet-A4",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device3-1": {
      type: "copper",
      apitype:"workshop-2p",
      connectedTo: "Cabinet-R1",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device3-2": {
      type: "copper",
      apitype:"workshop-2p",
      connectedTo: "Cabinet-R2",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device4-1": {
      type: "copper",
      apitype:"workshop-2p",
      connectedTo: "Cabinet-R3",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Device4-2": {
      type: "copper",
      apitype:"workshop-2p",
      connectedTo: "Cabinet-R4",
      wiremapstatus: "pass",
      performancestatus: "pass"
    }
  },
  DataCenter: {
    "CA-1A-1-port1": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port1",
      fiberstatus: "mm-pass"
    },
    "CA-1A-1-port2": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port2",
      fiberstatus: "mm-pass"
    },
    "CA-1A-1-port3": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port3",
      fiberstatus: "mm-pass"
    },
    "CA-1A-1-port4": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port4",
      fiberstatus: "mm-pass"
    },
    "CA-1A-1-port5": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port6",
      fiberstatus: "mm-pass"
    },
    "CA-1A-1-port6": {
      type: "fiber",
      apitype:"olts",
      connectedTo: "CB-1A-1-port6",
      fiberstatus: "mm-pass" 
    },
  },
  SkillCompetition: {
    "Room1-1": {
      type: "copper",
      connectedTo: "1A-1",
      wiremapstatus: "pass",
      performancestatus: "pass"
    },
    "Room1-2": {
      type: "copper",
      connectedTo: "1A-2",
      wiremapstatus: "open",
      performancestatus: "pass"
    },
    "Room2-1": {
      type: "copper",
      connectedTo: "1A-11",
      wiremapstatus: "short",
      performancestatus: "pass"
    },
    "Room2-2": {
      type: "copper",
      connectedTo: "1A-12",
      wiremapstatus: "cross",
      performancestatus: "pass"
    },
    "Room3-1": {
      type: "copper",
      connectedTo: "1B-5",
      wiremapstatus: "reversed",
      performancestatus: "pass"
    },
    "Room3-2": {
      type: "copper",
      connectedTo: "1B-6",
      wiremapstatus: "miswire",
      performancestatus: "pass"
    },
  },
  WorldSkill: {
  "Room1-TO-1": {
    type: "copper",
    apitype:"t568b",
    connectedTo: "1F-RackA-1A-1",
    wiremapstatus: "short2",
    performancestatus: "pass"
  },
  "Room1-TO-2": {
    type: "copper",
    apitype:"t568b",
    connectedTo: "1F-RackA-1A-2",
    wiremapstatus: "short",
    performancestatus: "pass"
  },
  "Room3-TO-1": {
    type: "copper",
    apitype:"t568b",
    connectedTo: "1F-RackA-1A-5",
    wiremapstatus: "cross",
    performancestatus: "next-fail"
  },
  "Room3-TO-2": {
    type: "copper",
    apitype:"t568b",
    connectedTo: "1F-RackA-1A-6",
    wiremapstatus: "reversed",
    performancestatus: "pass"
  },
  "Room4-CAM": {
    type: "copper",
    apitype:"t568b",
    connectedTo: "1F-RackA-1A-12",
    wiremapstatus: "pass",
    performancestatus: "mptl-nextfail"
  },
  // OLTS
  "2F-RackA-1A-1": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-1",
    fiberstatus: "sm-fail"
  },
  "2F-RackA-1A-2": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-2",
    fiberstatus: "sm-pass"
  },
  "2F-RackA-1A-3": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-3",
    fiberstatus: "sm-pass"
  },
  "2F-RackA-1A-4": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-4",
    fiberstatus: "sm-pass"
  },
  "2F-RackA-1A-5": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-6",
    fiberstatus: "sm-pass"
  },
  "2F-RackA-1A-6": {
    type: "fiber",
    apitype:"olts",
    connectedTo: "1F-RackA-1B-5",
    fiberstatus: "sm-pass"
  },
  // OTDR
  "1F-RackA-1C-1": {
    type: "fiber",
    apitype:"otdr",
    connectedTo: "x",
    fiberstatus: "sm-pass"
  },
   "1F-RackA-1C-2": {
    type: "fiber",
    apitype:"otdr",
    connectedTo: "x",
    fiberstatus: "connector-fail-start"
  },
   "1F-RackA-1C-3": {
    type: "fiber",
    apitype:"otdr",
    connectedTo: "x",
    fiberstatus: "splice-fail"
  },
   "1F-RackA-1C-4": {
    type: "fiber",
    apitype:"otdr",
    connectedTo: "x",
    fiberstatus: "bend"
  },
  // 车间
  "RMA-1": {
    type: "copper",
    apitype:"workshop-m12",
    connectedTo: "PLC-Rack-1A-1",
    wiremapstatus: "pass-2pair",
    performancestatus: "workshop-m12-pass-30m"
  },
  "RMA-2": {
    type: "copper",
    apitype:"workshop-m12",
    connectedTo: "PLC-Rack-1A-2",
    wiremapstatus: "sopen",
    performancestatus: "workshop-m12-pass-30m"
  },
  "PLC-Rack-1B-1": {
    type: "copper",
    apitype:"workshop-2p",
    connectedTo: "1F-RackA-1A-1",
    wiremapstatus: "pass-2pair",
    performancestatus: "workshop-2p-pass-80m"
  },
  "PLC-Rack-1B-2": {
    type: "copper",
    apitype:"workshop-2p",
    connectedTo: "1F-RackA-1A-2",
    wiremapstatus: "pass-2pair",
    performancestatus: "workshop-2p-pass-80m"
  },
  },
  CopperAnalyzer:{

  },
};

// 初始化连接映射数据
let connectionMap;
const connectionMapPath = path.join(__dirname, 'connection_maps', 'connectionMap.json');

try {
    if (fs.existsSync(connectionMapPath)) {
        const data = fs.readFileSync(connectionMapPath, 'utf8');
        connectionMap = JSON.parse(data);
        //console.log('从connectionMap.json加载连接映射数据');
    } else {
        connectionMap = JSON.parse(JSON.stringify(initialConnectionMap));
        //console.log('使用默认初始连接映射数据');
    }
} catch (err) {
    console.error('加载连接映射数据时出错:', err);
    connectionMap = JSON.parse(JSON.stringify(initialConnectionMap));
}

// 中间件
app.use(cors());
app.use(express.json());

// 获取连接映射的API
app.get('/api/connectionMap', (req, res) => {
  const scene = req.query.scene;

  if (!scene) {
    //console.log('[ERROR] 获取连接映射失败: 缺少scene参数');
    return res.status(400).json({ error: '缺少scene参数' });
  }

  if (!connectionMap[scene]) {
    //console.log(`[ERROR] 获取连接映射失败: 无效的场景 (${scene})`);
    return res.status(404).json({ error: '无效的场景' });
  }

  // 合并pass场景和当前场景的数据
  const mergedConnectionMap = Object.assign({}, connectionMap['pass'], connectionMap[scene]);
  //console.log(`[GET] 获取连接映射 - 场景: ${scene}`);
  res.json(mergedConnectionMap);
});



// 更新整个连接映射的API
app.post('/api/connectionMap', (req, res) => {
  const scene = Object.keys(req.body)[0];
  let newConnectionMap = req.body[scene];
  
  // 验证数据格式
  if (!scene || !newConnectionMap || typeof newConnectionMap !== 'object') {
    //console.log('[ERROR] 更新连接映射失败: 无效的数据格式');
    return res.status(400).json({ error: '无效的数据格式' });
  }
  
  // 禁止修改pass场景
  if (scene === 'pass') {
    //console.log('[ERROR] 更新连接映射失败: 不允许修改pass场景');
    return res.status(403).json({ error: '不允许修改pass场景' });
  }

  // 移除与pass场景重复的数据
  const passKeys = Object.keys(connectionMap.pass);
  newConnectionMap = Object.fromEntries(
    Object.entries(newConnectionMap).filter(([key]) => !passKeys.includes(key))
  );
  
  // 更新连接映射
  const oldConnectionMap = JSON.stringify(connectionMap[scene]);
  connectionMap[scene] = newConnectionMap;
  //console.log(`[UPDATE] 连接映射已更新 - 场景: ${scene}`);
  //console.log(`[DIFF] 旧数据: ${oldConnectionMap}`);
  //console.log(`[DIFF] 新数据: ${JSON.stringify(connectionMap[scene])}`);
  
  res.json({ success: true, message: '连接映射已更新' });
  // 持久化存储连接映射
  const fs = require('fs');
  const path = require('path');
  const dirPath = path.join(__dirname, 'connection_maps');
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath);
  }
  fs.writeFileSync(path.join(dirPath, `connectionMap.json`), JSON.stringify(connectionMap, null, 2));
  //console.log(`[SAVE] 连接映射已持久化存储`);
});

// 初始化连接映射的API
app.post('/api/initConnectionMap', (req, res) => {
  connectionMap = JSON.parse(JSON.stringify(initialConnectionMap));

  res.json({ success: true, message: '连接映射已恢复默认状态' });
    // 持久化存储连接映射
  const fs = require('fs');
  const path = require('path');
  const dirPath = path.join(__dirname, 'connection_maps');
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath);
  }
  fs.writeFileSync(path.join(dirPath, `connectionMap.json`), JSON.stringify(initialConnectionMap, null, 2));
  //console.log(`[SAVE] 连接映射已初始化并`);

});
// -----------------**************--------连接映射-----------***************--------------


// 比赛状态存储
let competitionStatus = {
  UUID: null,
  isRunning: false,
  startTime: null,
  statisticsData: {}
};

// 比赛开始API
app.post('/api/competition/start', (req, res) => {
  if (competitionStatus.isRunning) {
    return res.status(400).json({ error: '比赛已在进行中' });
  }
  
  competitionStatus = {
    UUID: require('crypto').randomUUID(),
    isRunning: true,
    startTime: new Date(new Date().getTime() + (8 * 60 * 60 * 1000)).toISOString(),
    statisticsData: {}
  };
  
// 创建比赛临时数据目录
  const tmpDirPath = path.join(__dirname, 'competition_tmp', competitionStatus.UUID);
  if (!fs.existsSync(path.join(__dirname, 'competition_tmp'))) {
    fs.mkdirSync(path.join(__dirname, 'competition_tmp'));
  }
  if (!fs.existsSync(tmpDirPath)) {
    fs.mkdirSync(tmpDirPath);
  }

  // 启动定时备份
  const backupInterval = setInterval(() => {
    if (!competitionStatus.isRunning) {
      clearInterval(backupInterval);
      return;
    }

    const timestamp = new Date(new Date().getTime() + (8 * 60 * 60 * 1000)).toISOString().replace(/[:.]/g, '-');
    const backupData = {
      connectionMap,
      competitionStatus
    };

    const dataStr = JSON.stringify(backupData, null, 2);
    const encodedData = encodeURIComponent(dataStr).split('').reverse().join('');
    const finalData = `EST_ENCODED_DATA:${encodedData}`;

    fs.writeFileSync(
      path.join(tmpDirPath, `backup_${timestamp}.est`),
      finalData
    );
    try {
      const maxAgeMs = 60 * 60 * 1000;
      const now = Date.now();
      const files = fs.readdirSync(tmpDirPath).filter(f => f.endsWith('.est'));
      for (const f of files) {
        const fp = path.join(tmpDirPath, f);
        const stat = fs.statSync(fp);
        if (now - stat.mtimeMs > maxAgeMs) {
          fs.unlinkSync(fp);
        }
      }
      const remaining = fs.readdirSync(tmpDirPath)
        .filter(f => f.endsWith('.est'))
        .map(f => {
          const fp = path.join(tmpDirPath, f);
          const stat = fs.statSync(fp);
          return { fp, mtimeMs: stat.mtimeMs };
        })
        .sort((a, b) => a.mtimeMs - b.mtimeMs);
      if (remaining.length > 60) {
        const excess = remaining.length - 60;
        for (let i = 0; i < excess; i++) {
          fs.unlinkSync(remaining[i].fp);
        }
      }
    } catch (e) {}
  }, 60000); // 每分钟备份一次

  //console.log(`[COMPETITION] 比赛开始 - UUID: ${competitionStatus.UUID}`);
  res.json({ success: true, UUID: competitionStatus.UUID });
});

// 比赛结束API
app.post('/api/competition/end', (req, res) => {
  if (!competitionStatus.isRunning) {
    return res.status(400).json({ error: '没有进行中的比赛' });
  }
  
  // 持久化存储比赛数据
  const fs = require('fs');
  const path = require('path');
  const dateStr = new Date().toISOString().split('T')[0];
  const fileName = `${dateStr}_${competitionStatus.UUID}.est`;
  const dirPath = path.join(__dirname, 'competition_data');
  const saveData = {
    connectionMap,
    competitionStatus,
  };
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath);
  }
  
  // 使用编码和简单的字符替换来编码数据
  const dataStr = JSON.stringify(saveData, null, 2);
  const encodedData = encodeURIComponent(dataStr).split('').reverse().join('');
  // 添加自定义头部标识，表明这是编码后的文件
  const finalData = `EST_ENCODED_DATA:${encodedData}`;
  
  fs.writeFileSync(
    path.join(dirPath, fileName),
    finalData
  );
  
  competitionStatus.isRunning = false;
  //console.log(`[COMPETITION] 比赛结束 - 数据已保存到 ${fileName}`);
  res.json({ 
    uuid: competitionStatus.UUID,
    success: true,
    data: saveData,
  });
  competitionStatus.statisticsData = {};
});

// 比赛状态查询API
app.get('/api/competition/status', (req, res) => {
  const response = {
    isRunning: competitionStatus.isRunning

  };
  
  if (competitionStatus.isRunning) {
    response.UUID = competitionStatus.UUID;
    response.startTime = competitionStatus.startTime;

  }
  
  res.json(response);
});




// 比赛数据上传API
app.post('/api/competition/data', (req, res) => {
  const { UUID, fingerprint, timestamp, data } = req.body;
  
  // 验证比赛状态
  if (!competitionStatus.isRunning) {
    return res.status(400).json({ error: '没有进行中的比赛' });
  }
  
  // 验证UUID
  if (!UUID || UUID !== competitionStatus.UUID) {
    return res.status(400).json({ error: '无效的UUID或UUID不匹配当前比赛' });
  }
  
  // 验证数据完整性
  if (!data || !fingerprint) {
    return res.status(400).json({ error: '缺少必要数据' });
  }

  try {
    // 使用指纹作为键，存储最新的数据
    competitionStatus.statisticsData[fingerprint] = {
      ...data,
      lastUpdate: timestamp
    };

  // 比赛数据查询API (根据UUID和fingerprint)
app.get('/api/competition/data', (req, res) => {
  const { UUID, fingerprint } = req.query;

  // 验证参数
  if (!UUID || !fingerprint) {
    //console.log('[ERROR] 查询比赛数据失败: 缺少UUID或fingerprint参数');
    return res.status(400).json({ error: '缺少UUID或fingerprint参数' });
  }

  // 检查比赛状态
  if (!competitionStatus.isRunning || competitionStatus.UUID !== UUID) {
    //console.log('[ERROR] 查询比赛数据失败: 无效的比赛UUID或比赛未进行');
    return res.status(404).json({ error: '无效的比赛UUID或比赛未进行' });
  }

  // 获取指定指纹的数据
  const data = competitionStatus.statisticsData[fingerprint];
  if (!data) {
    //console.log(`[WARN] 未找到指纹 ${fingerprint} 的比赛数据`);
    return res.status(404).json({ error: '未找到指定指纹的比赛数据' });
  }

  //console.log(`[GET] 获取比赛数据 - UUID: ${UUID}, 指纹: ${fingerprint}`);
  res.json({ 
    success: true,
    data: {
      projects: data.projects || []
    }
  });
});


    res.json({ success: true });
  } catch (error) {
    console.error('保存比赛数据失败:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

// 比赛数据查询API
app.get('/api/competition/data', (req, res) => {
  res.json(competitionStatus.statisticsData);
});


// -----------------**************--------教学数据-----------***************--------------

// 教学数据查询API
const teachingDir = path.join(__dirname, 'teaching_data');

app.post('/api/teaching/data', (req, res) => {
  const { fingerprint, scenario, timestamp, data } = req.body;
  if (!fingerprint || !scenario || !data) {
    return res.status(400).json({ error: '缺少必要参数' });
  }
  try {
    if (!fs.existsSync(teachingDir)) {
      fs.mkdirSync(teachingDir);
    }
    const filePath = path.join(teachingDir, `${scenario}.json`);
    let store = {};
    if (fs.existsSync(filePath)) {
      try {
        const content = fs.readFileSync(filePath, 'utf8');
        store = JSON.parse(content || '{}');
      } catch {
        store = {};
      }
    }
    store[fingerprint] = { ...data, lastUpdate: timestamp };
    fs.writeFileSync(filePath, JSON.stringify(store, null, 2));
    res.json({ success: true });
  } catch (error) {
    console.error('保存教学数据失败:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

app.get('/api/teaching/data', (req, res) => {
  const { scenario, fingerprint, org } = req.query;
  if (!scenario) {
    return res.status(400).json({ error: '缺少scenario参数' });
  }
  try {
    if (!fs.existsSync(teachingDir)) {
      if (fingerprint) {
        return res.status(404).json({ error: '未找到指定指纹数据' });
      }
      if (!org) {
        return res.status(400).json({ error: '缺少org参数' });
      }
      return res.json({});
    }
    const filePath = path.join(teachingDir, `${scenario}.json`);
    if (!fs.existsSync(filePath)) {
      if (fingerprint) {
        return res.status(404).json({ error: '未找到指定指纹数据' });
      }
      if (!org) {
        return res.status(400).json({ error: '缺少org参数' });
      }
      return res.json({});
    }
    const content = fs.readFileSync(filePath, 'utf8');
    const store = JSON.parse(content || '{}');
    if (fingerprint) {
      const entry = store[fingerprint] || null;
      if (!entry) {
        return res.status(404).json({ error: '未找到指定指纹数据' });
      }
      if (org && String(entry.org || '').toLowerCase() !== String(org).toLowerCase()) {
        return res.status(404).json({ error: '未找到指定指纹数据' });
      }
      return res.json(entry);
    }
    if (!org) {
      return res.status(400).json({ error: '缺少org参数' });
    }
    const filtered = Object.fromEntries(
      Object.entries(store).filter(([_, v]) => String((v && v.org) || '').toLowerCase() === String(org).toLowerCase())
    );
    return res.json(filtered);
  } catch (error) {
    console.error('读取教学数据失败:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

app.post('/api/teaching/clear', (req, res) => {
  const { scenario, org, fingerprint } = req.body;
  if (!scenario) {
    return res.status(400).json({ error: '缺少scenario参数' });
  }
  try {
    if (!fs.existsSync(teachingDir)) {
      return res.json({ success: true });
    }
    const filePath = path.join(teachingDir, `${scenario}.json`);
    if (!fs.existsSync(filePath)) {
      return res.json({ success: true });
    }
    if (!org && !fingerprint) {
      fs.unlinkSync(filePath);
      return res.json({ success: true });
    }
    const content = fs.readFileSync(filePath, 'utf8');
    const store = JSON.parse(content || '{}');
    if (fingerprint) {
      const entry = store[fingerprint];
      if (!entry) {
        return res.json({ success: true });
      }
      if (org && String(entry.org || '').toLowerCase() !== String(org).toLowerCase()) {
        return res.json({ success: true });
      }
      delete store[fingerprint];
      fs.writeFileSync(filePath, JSON.stringify(store, null, 2));
      return res.json({ success: true });
    }
    if (org) {
      const filtered = Object.fromEntries(
        Object.entries(store).filter(([_, v]) => String((v && v.org) || '').toLowerCase() !== String(org).toLowerCase())
      );
      fs.writeFileSync(filePath, JSON.stringify(filtered, null, 2));
      return res.json({ success: true });
    }
    res.json({ success: true });
  } catch (error) {
    console.error('清除教学数据失败:', error);
    res.status(500).json({ error: '服务器内部错误' });
  }
});

// -----------------**************--------------------------***************--------------



// 启动服务器
if (require.main === module) {
  app.listen(PORT, () => {
    console.log(`[SERVER] 服务器运行在 http://localhost:${PORT}`);
    console.log('\x1b[31m%s\x1b[0m', '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
    console.log('\x1b[31m\x1b[1m%s\x1b[0m', '!!   比赛期间请勿关闭此窗口     !!');
    console.log('\x1b[31m\x1b[1m%s\x1b[0m', '!!   比赛期间避免键盘操作 如Ctrl+C等   !!');
    console.log('\x1b[31m\x1b[1m%s\x1b[0m', '!!   关闭后比赛数据将会丢失   !!');
    console.log('\x1b[31m%s\x1b[0m', '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
  });
}

module.exports = app;
