const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
const path = require('path');
const fs = require('fs');
const { MessageHistory } = require('./src/message_history.js');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  pingTimeout: 300000,    // 60秒超时
  pingInterval: 25000,   // 25秒心跳间隔
  upgradeTimeout: 30000, // 30秒升级超时
  allowEIO3: true,       // 允许Engine.IO v3客户端
  transports: ['websocket', 'polling'], // 支持多种传输方式
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

// 创建消息历史管理器
const messageHistory = new MessageHistory();

// 服务器启动时初始化历史消息
async function initializeServer() {
    try {
        await messageHistory.initialize();
        console.log('消息历史初始化完成');
    } catch (error) {
        console.error('初始化消息历史失败:', error);
    }
}

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.static('src'));
app.use('/videos', express.static('videos'));

// API路由 - 获取历史消息（用于LLM上下文）
app.get('/api/messages/for-llm', (req, res) => {
    try {
        const { includeSystem = true, recentCount = 5 } = req.query;
        const messages = messageHistory.getMessagesForLLM(
            includeSystem === 'true', 
            parseInt(recentCount)
        );
        res.json({ messages });
    } catch (error) {
        console.error('获取LLM消息失败:', error);
        res.status(500).json({ error: '获取消息失败' });
    }
});

// API路由 - 保存新消息
app.post('/api/messages/save', async (req, res) => {
    try {
        const { userInput, assistantResponse } = req.body;
        if (!userInput || !assistantResponse) {
            return res.status(400).json({ error: '缺少必要参数' });
        }
        
        await messageHistory.addMessage(userInput, assistantResponse);
        res.json({ success: true, message: '消息已保存' });
    } catch (error) {
        console.error('保存消息失败:', error);
        res.status(500).json({ error: '保存消息失败' });
    }
});

// API路由 - 获取完整历史（可选，用于调试或展示）
app.get('/api/messages/history', (req, res) => {
    try {
        const history = messageHistory.getFullHistory();
        res.json({ history });
    } catch (error) {
        console.error('获取历史消息失败:', error);
        res.status(500).json({ error: '获取历史消息失败' });
    }
});

// API路由 - 清空历史
app.delete('/api/messages/clear', async (req, res) => {
    try {
        await messageHistory.clearHistory();
        res.json({ success: true, message: '历史消息已清空' });
    } catch (error) {
        console.error('清空历史消息失败:', error);
        res.status(500).json({ error: '清空历史消息失败' });
    }
});

// 存储连接的客户端和他们的视频流状态
const connectedClients = new Map();

// 场景轮询系统
// 场景轮询系统 - 添加持久化
// 删除这行：const fs = require('fs');  // 重复声明，需要删除
const sceneStateFile = path.join(__dirname, 'scene_state.json');

// 从文件加载场景状态
function loadSceneState() {
  try {
    if (fs.existsSync(sceneStateFile)) {
      const data = fs.readFileSync(sceneStateFile, 'utf8');
      const state = JSON.parse(data);
      currentSceneIndex = state.currentSceneIndex || 0;
      console.log(`从文件加载场景状态: ${currentSceneIndex} (${scenes[currentSceneIndex].name})`);
    } else {
      console.log('场景状态文件不存在，使用默认值: 0');
    }
  } catch (error) {
    console.error('加载场景状态失败:', error);
    currentSceneIndex = 0;
  }
}

// 保存场景状态到文件
function saveSceneState() {
  try {
    const state = { currentSceneIndex };
    fs.writeFileSync(sceneStateFile, JSON.stringify(state, null, 2));
    console.log(`场景状态已保存: ${currentSceneIndex}`);
  } catch (error) {
    console.error('保存场景状态失败:', error);
  }
}

let currentSceneIndex = 0;
const scenes = [
  {
    name: '起床-坐在床上',
    defaultVideo: '8-5-qc-bd-female.mp4',
    interactionVideo: '8-5-qc-sh-female.mp4',
    tag: 'wakeup',
    apiKey: 'bot-20250730213756-l627w', // 起床场景的API key
    openingLines: [
      '哈啊~ 头发是不是超乱？别笑话我哦... 不过，能看到你的脸，就算乱糟糟的我也好开心。',
      "刚醒就看到你，比闹钟好使一百倍。",
      // "昨晚梦里喊你名字喊醒了，现在视频看到你，心跳比梦里还烫。",
      // "你穿我T恤的样子...让我想咬住衣领不放。",
      "宝宝早安！偷偷告诉你...我昨晚梦见你啦，所以醒来第一件事就是找你~",
      // "喉咙里有咖啡味...要不要来尝尝？记得上次你咬我锁骨时，咖啡还温着。",
      "早，宝宝。吃早餐没？我还没... 好想有人送早餐来床上哦。"
    ]
  },
  {
    name: '走路去公司的路上',
    defaultVideo: '8-5-sb-bd-female.mp4',
    interactionVideo: '8-5-sb-sh-female.mp4',
    tag: 'walk',
    apiKey: 'bot-20250703161810-sgkrh', // 开车场景的API key
    openingLines: [
      '宝宝，看到你那边阳光好好哦。我这边有点风，吹着挺舒服的，要是你在旁边牵着手就更好了。',
      '宝宝，我快到公司啦。今天太阳真好，晒得人暖暖的... 你那边天气咋样？',
      '宝宝~ 我刚出地铁站就看到你啦！吃早餐没？',
      // '看到那个大钟楼没？每次路过都想你。想着要是能牵着你的手，站在最高层往下看该多好。',
      '宝宝，我快到公司了，你到公司了吗？',
      '宝宝，今天太阳真舒服！想起昨晚说的周末想去湖边散步，要是这天气保持住就好啦！',
    ]
  },
  {
    name: '在公司楼下喝咖啡',
    defaultVideo: '8-8-hc-bd-2.mp4',
    interactionVideo: '8-5-hc-sh-female.mp4',
    tag: 'coffee',
    apiKey: 'bot-20250805140055-ccdr6', // 喝茶场景的API key
    openingLines: [
      '宝宝，今天这杯拿铁拉花好丑哦... 不过没关系，看着你的帅脸就平衡啦，你比咖啡提神！',
      '嗯... 咖啡香香的，宝宝的声音也好好听。好想时间停在这一小会儿，就我们俩。',
      '哇，今天换了个口味，燕麦拿铁！宝宝你肯定嫌没味道，就爱喝你那美式... 苦死了。',
      '宝宝，刚才店员问我糖浆加多少，我脱口而出‘和我男朋友一样’，说完自己都脸红了...',
      '对了宝宝，昨天说帮你找的资料，我存手机了，喝完这杯咖啡就发你哈！记得看。',
      // '这杯好苦…但一看到你，就自动回甘了。比加十包糖都管用。你说你是不是我的专属甜味剂？'
    ]
  },
  {
    name: '敷面膜-准备睡觉',
    defaultVideo: '8-8-sj-bd.mp4',
    interactionVideo: '8-8-sj-sh.mp4',
    tag: 'sleep',
    apiKey: 'bot-20250808120020-jfkmk', // 睡觉场景的API key
    openingLines: [
      '宝宝~ 敷着面膜和你视频，感觉像在做双倍美容，心里也美美的。',
      '嗯？宝宝打来啦... 刚躺下贴上面膜，你就来了，像算准时间一样，真贴心。',
      '哈，宝宝，选了个清洁面膜，有点刺刺的。你用的啥洗面奶来着？忘了...',
      '早...哦不，晚安宝宝！敷面膜呢，你看我像不像外星人？哈哈...，不许笑我！',
      '宝宝，你那边也躺下了？我弄完面膜就睡。今天累不累？',
      '宝宝... 这面膜说要敷15分钟，正好陪你唠会儿。不过我得小声，怕长皱纹！',
      '好啦宝宝，面膜快干了，得去洗了。你先睡？... 嗯，梦里见呗。'
    ]
  }
];

// 获取当前场景
function getCurrentScene() {
  return scenes[currentSceneIndex];
}

// 切换到下一个场景 - 改进版
function switchToNextScene() {
  const previousIndex = currentSceneIndex;
  const previousScene = scenes[previousIndex].name;
  
  currentSceneIndex = (currentSceneIndex + 1) % scenes.length;
  const newScene = getCurrentScene();
  
  console.log(`场景切换: ${previousScene}(${previousIndex}) → ${newScene.name}(${currentSceneIndex})`);
  
  // 保存状态到文件
  saveSceneState();
  
  return newScene;
}

// 在服务器启动时加载场景状态
async function initializeServer() {
    try {
        // 加载场景状态
        loadSceneState();
        
        await messageHistory.initialize();
        console.log('消息历史初始化完成');
        console.log(`当前场景: ${getCurrentScene().name} (索引: ${currentSceneIndex})`);
    } catch (error) {
        console.error('初始化服务器失败:', error);
    }
}

// 视频映射配置 - 动态更新
function getVideoMapping() {
  const currentScene = getCurrentScene();
  return {
    'defaultVideo': currentScene.defaultVideo,
    'interactionVideo': currentScene.interactionVideo,
    'tag': currentScene.tag
  };
}

// 默认视频流配置 - 动态获取
function getDefaultVideo() {
  return getCurrentScene().defaultVideo;
}

let currentScene = getCurrentScene();

// 视频映射配置
const videoMapping = {
  // 'say-6s-m-e': '1-m.mp4',
  'default': currentScene.defaultVideo,
  '8-4-sh': currentScene.interactionVideo,
  'tag': currentScene.tag
  // 'say-5s-amplitude': '2.mp4',
  // 'say-5s-m-e': '4.mp4',
  // 'say-5s-m-sw': 'd-0.mp4',
  // 'say-3s-m-sw': '6.mp4',
};

// 默认视频流配置
const DEFAULT_VIDEO = currentScene.defaultVideo;
const INTERACTION_TIMEOUT = 10000; // 10秒后回到默认视频

// 获取视频列表
app.get('/api/videos', (req, res) => {
  const videosDir = path.join(__dirname, 'videos');
  fs.readdir(videosDir, (err, files) => {
    if (err) {
      return res.status(500).json({ error: '无法读取视频目录' });
    }
    const videoFiles = files.filter(file => 
      file.endsWith('.mp4') || file.endsWith('.webm') || file.endsWith('.avi')
    );
    res.json({ videos: videoFiles });
  });
});

// 获取当前场景信息的API接口
app.get('/api/current-scene', (req, res) => {
    const scene = getCurrentScene();
    res.json({
        name: scene.name,
        tag: scene.tag,
        apiKey: scene.apiKey,
        defaultVideo: scene.defaultVideo,
        interactionVideo: scene.interactionVideo
    });
});

// 获取视频映射
app.get('/api/video-mapping', (req, res) => {
  const currentMapping = getVideoMapping();
  const dynamicMapping = {
    'default': currentMapping.defaultVideo,
    '8-4-sh': currentMapping.interactionVideo,
    'tag': currentMapping.tag
  };
  res.json({ mapping: dynamicMapping });
});

// 获取默认视频
app.get('/api/default-video', (req, res) => {
  res.json({ 
    defaultVideo: getDefaultVideo(),
    autoLoop: true
  });
});

// 在现有的API接口后添加
app.get('/api/current-scene/opening-line', (req, res) => {
  try {
    const currentScene = getCurrentScene();
    if (currentScene && currentScene.openingLines && currentScene.openingLines.length > 0) {
      // 随机选择一个开场白
      const randomIndex = Math.floor(Math.random() * currentScene.openingLines.length);
      const selectedOpeningLine = currentScene.openingLines[randomIndex];
      
      res.json({
        success: true,
        openingLine: selectedOpeningLine,
        sceneName: currentScene.name,
        sceneTag: currentScene.tag
      });
    } else {
      res.json({
        success: false,
        message: '当前场景没有配置开场白'
      });
    }
  } catch (error) {
    console.error('获取开场白失败:', error);
    res.status(500).json({
      success: false,
      message: '获取开场白失败',
      error: error.message
    });
  }
});

// Socket.IO 连接处理
io.on('connection', (socket) => {
  console.log('用户连接:', socket.id);
  connectedClients.set(socket.id, {
    socket: socket,
    currentVideo: getDefaultVideo(),
    isInInteraction: false,
    hasTriggeredSceneSwitch: false  // 添加这个标志
  });

  // 处理WebRTC信令 - 用于传输视频流
  socket.on('offer', (data) => {
    console.log('收到offer:', socket.id);
    socket.broadcast.emit('offer', {
      ...data,
      from: socket.id
    });
  });

  socket.on('answer', (data) => {
    console.log('收到answer:', socket.id);
    socket.broadcast.emit('answer', {
      ...data,
      from: socket.id
    });
  });

  socket.on('ice-candidate', (data) => {
    console.log('收到ice-candidate:', socket.id);
    socket.broadcast.emit('ice-candidate', {
      ...data,
      from: socket.id
    });
  });

  // 处理视频流切换请求
  socket.on('switch-video-stream', (data) => {
    const { videoFile, type, text } = data;
    console.log(`用户 ${socket.id} 请求切换视频流: ${videoFile} (${type})`);
    
    // 更新客户端状态
    const client = connectedClients.get(socket.id);
    if (client) {
      client.currentVideo = videoFile;
      client.isInInteraction = true;
    }
    
    // 广播视频流切换指令给所有用户
    io.emit('video-stream-switched', { 
      videoFile, 
      type, 
      text,
      from: socket.id 
    });
    
    // 如果是交互类型，设置定时器回到默认视频
    // if (type === 'text' || type === 'voice') {
    //   setTimeout(() => {
    //     console.log(`交互超时，用户 ${socket.id} 回到默认视频`);
    //     if (client) {
    //       client.currentVideo = getDefaultVideo();
    //       client.isInInteraction = false;
    //     }
    //     // 广播回到默认视频的指令
    //     io.emit('video-stream-switched', { 
    //       videoFile: getDefaultVideo(), 
    //       type: 'default',
    //       from: socket.id 
    //     });
    //   }, INTERACTION_TIMEOUT);
    // }
  });

  // 处理通话开始
  socket.on('call-started', () => {
    console.log('通话开始，用户:', socket.id);
    const client = connectedClients.get(socket.id);
    if (client) {
      client.currentVideo = getDefaultVideo();
      client.isInInteraction = false;
    }
    io.emit('call-started', { from: socket.id });
  });

  // 处理文本输入
  socket.on('text-input', (data) => {
    const { text } = data;
    console.log('收到文本输入:', text, '来自用户:', socket.id);
    
    // 根据文本查找对应视频
    let videoFile = videoMapping['default'];
    for (const [key, value] of Object.entries(videoMapping)) {
      if (text.toLowerCase().includes(key.toLowerCase())) {
        videoFile = value;
        break;
      }
    }
    
    console.log(`用户 ${socket.id} 文本输入 "${text}" 对应视频: ${videoFile}`);
    
    // 发送视频流切换请求
    socket.emit('switch-video-stream', { 
      videoFile, 
      type: 'text', 
      text 
    });
  });

  // 处理语音输入
  socket.on('voice-input', (data) => {
    const { audioData, text } = data;
    console.log('收到语音输入:', text, '来自用户:', socket.id);
    
    // 根据语音识别的文本查找对应视频
    let videoFile = videoMapping['default'];
    for (const [key, value] of Object.entries(videoMapping)) {
      if (text.toLowerCase().includes(key.toLowerCase())) {
        videoFile = value;
        break;
      }
    }
    
    console.log(`用户 ${socket.id} 语音输入 "${text}" 对应视频: ${videoFile}`);
    
    // 发送视频流切换请求
    socket.emit('switch-video-stream', { 
      videoFile, 
      type: 'voice', 
      text 
    });
  });

  // 处理回到默认视频请求
  socket.on('return-to-default', () => {
    console.log('用户请求回到默认视频:', socket.id);
    const client = connectedClients.get(socket.id);
    if (client) {
      client.currentVideo = getDefaultVideo();
      client.isInInteraction = false;
    }
    socket.emit('switch-video-stream', { 
      videoFile: getDefaultVideo(), 
      type: 'default' 
    });
  });

  // 处理用户关闭连接事件
  socket.on('user-disconnect', () => {
    console.log('=== 场景切换开始 ===');
    console.log('用户主动关闭连接:', socket.id);
    console.log('切换前场景:', getCurrentScene().name, '(索引:', currentSceneIndex, ')');
    
    // 切换到下一个场景
    const newScene = switchToNextScene();
    console.log('切换后场景:', newScene.name, '(索引:', currentSceneIndex, ')');
    
    // 检查是否已经处理过场景切换
    const client = connectedClients.get(socket.id);
    if (client && client.hasTriggeredSceneSwitch) {
      console.log('场景切换已处理，跳过重复触发');
      return;
    }
    
    // 标记已处理场景切换
    if (client) {
      client.hasTriggeredSceneSwitch = true;
    }
    
    // 更新videoMapping
    const newMapping = getVideoMapping();
    videoMapping['default'] = newMapping.defaultVideo;
    videoMapping['8-4-sh'] = newMapping.interactionVideo;
    videoMapping['tag'] = newMapping.tag;
    
    // 广播场景切换事件给所有客户端
    io.emit('scene-switched', {
        scene: newScene,
        mapping: {
            defaultVideo: newMapping.defaultVideo,
            interactionVideo: newMapping.interactionVideo,
            tag: newMapping.tag,
            'default': newMapping.defaultVideo,
            '8-4-sh': newMapping.interactionVideo
        },
        from: socket.id
    });
  });

  // 断开连接
  socket.on('disconnect', () => {
    console.log('用户断开连接:', socket.id);
    connectedClients.delete(socket.id);
  });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, '0.0.0.0', async () => {
    console.log(`服务器运行在端口 ${PORT}`);
    await initializeServer();
});

// 导出消息历史管理器供其他模块使用
module.exports = { messageHistory };
console.log(`访问 http://localhost:${PORT} 开始使用`);
