/**
 * Conversation routes — /api/conversation*, /api/chat/state, /api/chat/history, /api/sessions
 */
import fs from 'fs';
import path from 'path';

export function setupConversationRoutes(app, server) {
  // --- Session restore status (used by frontend on page load) ---
  app.get('/api/session/:chatId/status', (req, res) => {
    const chatId = req.params.chatId;
    const session = server.sessionPool.get(chatId);
    if (session) {
      // Session alive in memory
      res.json({
        restored: true,
        source: 'memory',
        messageCount: session.contextManager.messages.length,
        turnCount: session.contextManager.turnCount,
        todos: session.orchestrator?.todos || [],
        convName: session.convName || null,
      });
    } else {
      // Try to get or create (will auto-restore from disk)
      const s = server.sessionPool.getOrCreate(chatId);
      const msgCount = s.contextManager.messages.length;
      res.json({
        restored: msgCount > 0,
        source: msgCount > 0 ? 'disk' : 'new',
        messageCount: msgCount,
        turnCount: s.contextManager.turnCount,
        todos: s.orchestrator?.todos || [],
        convName: s.convName || null,
      });
    }
  });

  // --- Sessions list ---
  app.get('/api/sessions', (_req, res) => {
    const sessions = server.sessionPool.list();
    res.json(sessions);
  });

  app.get('/api/session/:chatId/summary', (req, res) => {
    const session = server.sessionPool.get(req.params.chatId);
    if (!session) return res.status(404).json({ error: 'Session not found' });
    const messages = session.contextManager.messages.slice(-10).map(m => ({
      role: m.role,
      preview: typeof m.content === 'string' ? m.content.substring(0, 200) : '[complex]',
    }));
    res.json({ chatId: req.params.chatId, messages });
  });

  // --- Conversations (multi-tab) ---
  app.get('/api/conversations', (_req, res) => {
    res.json(server._convRegistry);
  });

  // --- Get display messages for a conversation (for DOM rebuild on other windows) ---
  app.get('/api/conversations/:id/messages', (req, res) => {
    const chatId = req.params.id;
    const session = server.sessionPool.get(chatId);
    if (!session) return res.json({ messages: [] });
    const raw = session.contextManager.messages || [];
    const messages = [];
    for (const m of raw) {
      if (m.role !== 'user' && m.role !== 'assistant') continue;
      let text = '';
      if (typeof m.content === 'string') {
        text = m.content;
      } else if (Array.isArray(m.content)) {
        text = m.content.filter(b => b.type === 'text').map(b => b.text).join('');
      }
      if (text.trim()) messages.push({ role: m.role, content: text });
    }
    res.json({ messages });
  });

  app.post('/api/conversations', (req, res) => {
    const { name } = req.body;
    const id = server._convRegistry.convIdCounter++;
    const conv = { id, name: name || `Chat ${id + 1}`, dom: '' };
    server._convRegistry.conversations.push(conv);
    server._convRegistry.activeConvId = id;
    server.persistChatState();
    res.json(conv);
  });

  app.patch('/api/conversations/:id', (req, res) => {
    const id = parseInt(req.params.id);
    const conv = server._convRegistry.conversations.find(c => c.id === id);
    if (!conv) return res.status(404).json({ error: 'Conversation not found' });
    if (req.body.name !== undefined) conv.name = req.body.name;
    if (req.body.dom !== undefined) conv.dom = req.body.dom;
    server.persistChatState();
    res.json(conv);
  });

  app.delete('/api/conversations/:id', (req, res) => {
    const id = parseInt(req.params.id);
    server._convRegistry.conversations = server._convRegistry.conversations.filter(c => c.id !== id);
    // If the deleted conversation was active, fall back to the first remaining one (or 0)
    if (server._convRegistry.activeConvId === id) {
      const remaining = server._convRegistry.conversations;
      server._convRegistry.activeConvId = remaining.length > 0 ? remaining[0].id : 0;
    }
    // Also delete session
    server.sessionPool.delete(String(id));
    server.persistChatState();
    res.json({ ok: true });
  });

  app.delete('/api/conversations', (_req, res) => {
    server._convRegistry.conversations = [{ id: 0, name: 'Chat 1', dom: '' }];
    server._convRegistry.activeConvId = 0;
    server._convRegistry.convIdCounter = 1;
    // Clear all sessions including '0' (Chat 1 context must be wiped too)
    for (const [chatId] of server.sessionPool._sessions) {
      server.sessionPool.delete(chatId);
    }
    server.persistChatState();
    res.json({ ok: true });
  });

  // --- Chat state (backend source of truth) ---
  app.get('/api/chat/state', (_req, res) => {
    res.json(server._convRegistry);
  });

  app.post('/api/chat/state', (req, res) => {
    if (req.body.conversations) server._convRegistry.conversations = req.body.conversations;
    if (req.body.activeConvId !== undefined) server._convRegistry.activeConvId = req.body.activeConvId;
    if (req.body.convIdCounter !== undefined) server._convRegistry.convIdCounter = req.body.convIdCounter;
    server.persistChatState();
    res.json({ ok: true });
  });

  // --- Chat persistence ---
  app.post('/api/chat/persist', (req, res) => {
    try {
      const { id, name, dom, messages } = req.body;
      const persistDir = path.join(server.config.workDir, '.vl-code', 'chats');
      if (!fs.existsSync(persistDir)) fs.mkdirSync(persistDir, { recursive: true });
      const filename = `chat-${id}-${Date.now()}.json`;
      fs.writeFileSync(path.join(persistDir, filename), JSON.stringify({ id, name, dom, messages, savedAt: new Date().toISOString() }, null, 2));
      res.json({ ok: true, filename });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  app.get('/api/chat/persist', (req, res) => {
    try {
      const persistDir = path.join(server.config.workDir, '.vl-code', 'chats');
      if (!fs.existsSync(persistDir)) return res.json([]);
      const files = fs.readdirSync(persistDir).filter(f => f.endsWith('.json')).sort().reverse();
      const chats = files.slice(0, 50).map(f => {
        try {
          const data = JSON.parse(fs.readFileSync(path.join(persistDir, f), 'utf-8'));
          return { filename: f, id: data.id, name: data.name, savedAt: data.savedAt };
        } catch { return null; }
      }).filter(Boolean);
      res.json(chats);
    } catch { res.json([]); }
  });

  app.get('/api/chat/persist/:id', (req, res) => {
    try {
      const persistDir = path.join(server.config.workDir, '.vl-code', 'chats');
      const fp = path.join(persistDir, req.params.id);
      if (fs.existsSync(fp)) res.json(JSON.parse(fs.readFileSync(fp, 'utf-8')));
      else res.status(404).json({ error: 'Not found' });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Generate title ---
  app.post('/api/chat/generate-title', async (req, res) => {
    try {
      const { messages } = req.body;
      if (!messages?.length) return res.json({ title: 'New Chat' });
      const preview = messages.slice(0, 3).map(m => (typeof m === 'string' ? m : m.content || '')).join(' ').substring(0, 200);
      // Simple heuristic title
      const words = preview.split(/\s+/).slice(0, 5).join(' ');
      res.json({ title: words || 'New Chat' });
    } catch (e) { res.json({ title: 'New Chat' }); }
  });

  // --- Chat history ---
  app.get('/api/chat/history', (req, res) => {
    try {
      const persistDir = path.join(server.config.workDir, '.vl-code', 'chats');
      if (!fs.existsSync(persistDir)) return res.json([]);
      const files = fs.readdirSync(persistDir).filter(f => f.endsWith('.json')).sort().reverse();
      const history = files.slice(0, 100).map(f => {
        try {
          const data = JSON.parse(fs.readFileSync(path.join(persistDir, f), 'utf-8'));
          return { filename: f, name: data.name, savedAt: data.savedAt, messageCount: data.messages?.length || 0 };
        } catch { return null; }
      }).filter(Boolean);
      res.json(history);
    } catch { res.json([]); }
  });

  // --- Debug log persistence ---
  app.post('/api/debug-log/persist', (req, res) => {
    try {
      const logDir = path.join(server.config.workDir, '.vl-code', 'logs');
      if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
      const filename = `debug-${Date.now()}.json`;
      fs.writeFileSync(path.join(logDir, filename), JSON.stringify(req.body, null, 2));
      res.json({ ok: true, filename });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- History search ---
  app.get('/api/history/search', (req, res) => {
    const q = (req.query.q || '').toLowerCase();
    if (!q) return res.json([]);
    const session = server.getSession(req);
    const matches = session.contextManager.messages
      .map((m, i) => ({ role: m.role, idx: i, content: typeof m.content === 'string' ? m.content : '' }))
      .filter(m => m.content.toLowerCase().includes(q))
      .slice(0, 20)
      .map(m => ({ ...m, content: m.content.substring(0, 200) }));
    res.json(matches);
  });

  // --- Plan mode ---
  app.post('/api/plan/enter', (req, res) => {
    const session = server.getSession(req);
    session.orchestrator?.enterPlanMode?.();
    res.json({ ok: true });
  });

  app.post('/api/plan/approve', async (req, res) => {
    const session = server.getSession(req);
    session.orchestrator?.exitPlanMode?.();
    res.json({ ok: true });
  });

  app.post('/api/plan/cancel', (req, res) => {
    const session = server.getSession(req);
    if (session.orchestrator?.planMode) session.orchestrator.planMode = false;
    res.json({ ok: true });
  });

  app.get('/api/plan/status', (req, res) => {
    const session = server.getSession(req);
    res.json({ planMode: !!session.orchestrator?.planMode });
  });
}
