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

const app = express();
const PORT = 8890;

const SESSIONS_DIR = '/Users/jakeshore/.clawdbot/agents/main/sessions';
const WORKSPACE = '/Users/jakeshore/.clawdbot/workspace';
const MEMORY_DIR = path.join(WORKSPACE, 'memory');

// Serve static files
app.use(express.static(path.join(__dirname, 'public')));

// Parse JSONL file (last N lines for efficiency)
async function parseSessionFile(filePath, maxLines = 50) {
  const messages = [];
  try {
    const content = fs.readFileSync(filePath, 'utf8');
    const lines = content.trim().split('\n').slice(-maxLines);
    for (const line of lines) {
      try {
        const parsed = JSON.parse(line);
        messages.push(parsed);
      } catch (e) { /* skip malformed */ }
    }
  } catch (e) { /* file not readable */ }
  return messages;
}

// Get all sessions with metadata
function getSessionFiles() {
  try {
    const files = fs.readdirSync(SESSIONS_DIR)
      .filter(f => f.endsWith('.jsonl'))
      .map(f => {
        const fullPath = path.join(SESSIONS_DIR, f);
        const stat = fs.statSync(fullPath);
        return {
          id: f.replace('.jsonl', ''),
          file: f,
          path: fullPath,
          size: stat.size,
          modified: stat.mtime,
          created: stat.ctime,
        };
      })
      .sort((a, b) => b.modified - a.modified);
    return files;
  } catch (e) {
    return [];
  }
}

// Extract activity from messages
function extractActivity(messages, sessionId) {
  const activities = [];
  for (const msg of messages) {
    const ts = msg.timestamp || msg.ts || null;
    
    if (msg.role === 'user') {
      const content = typeof msg.content === 'string' ? msg.content : 
        Array.isArray(msg.content) ? msg.content.map(c => c.text || '').join(' ') : '';
      if (content && !content.startsWith('HEARTBEAT')) {
        activities.push({
          type: 'user_message',
          session: sessionId,
          content: content.substring(0, 200),
          timestamp: ts,
        });
      }
    }
    
    if (msg.role === 'assistant') {
      const content = typeof msg.content === 'string' ? msg.content :
        Array.isArray(msg.content) ? msg.content.map(c => c.text || '').join(' ') : '';
      
      // Check for tool use
      if (Array.isArray(msg.content)) {
        for (const block of msg.content) {
          if (block.type === 'tool_use') {
            activities.push({
              type: 'tool_call',
              session: sessionId,
              tool: block.name,
              content: block.name + (block.input?.command ? ': ' + block.input.command.substring(0, 80) : 
                block.input?.action ? ': ' + block.input.action : 
                block.input?.query ? ': ' + block.input.query.substring(0, 80) : ''),
              timestamp: ts,
            });
          }
        }
      }
      
      if (content && content !== 'NO_REPLY' && content !== 'HEARTBEAT_OK') {
        activities.push({
          type: 'buba_reply',
          session: sessionId,
          content: content.substring(0, 200),
          timestamp: ts,
        });
      }
    }
  }
  return activities;
}

// API: Dashboard state
app.get('/api/state', async (req, res) => {
  try {
    const sessions = getSessionFiles();
    const now = Date.now();
    const oneHourAgo = now - (60 * 60 * 1000);
    const oneDayAgo = now - (24 * 60 * 60 * 1000);
    
    // Categorize sessions
    const activeSessions = sessions.filter(s => s.modified.getTime() > oneHourAgo);
    const recentSessions = sessions.filter(s => s.modified.getTime() > oneDayAgo);
    const subagentSessions = sessions.filter(s => s.id.includes('subagent'));
    const activeSubagents = subagentSessions.filter(s => s.modified.getTime() > oneHourAgo);
    
    // Parse main session for recent activity
    const mainSession = sessions.find(s => !s.id.includes('subagent'));
    let recentActivity = [];
    
    // Get activity from recent sessions
    const sessionsToScan = sessions.slice(0, 10);
    for (const session of sessionsToScan) {
      const messages = await parseSessionFile(session.path, 20);
      const activity = extractActivity(messages, session.id);
      recentActivity.push(...activity);
    }
    
    // Sort by recency and limit
    recentActivity.sort((a, b) => {
      const ta = a.timestamp ? new Date(a.timestamp).getTime() : 0;
      const tb = b.timestamp ? new Date(b.timestamp).getTime() : 0;
      return tb - ta;
    });
    recentActivity = recentActivity.slice(0, 50);
    
    // Read working state
    let workingState = '';
    try {
      workingState = fs.readFileSync(path.join(MEMORY_DIR, 'working-state.md'), 'utf8');
    } catch (e) { }
    
    // Read today's log
    let todayLog = '';
    const today = new Date().toISOString().split('T')[0];
    try {
      todayLog = fs.readFileSync(path.join(MEMORY_DIR, `${today}.md`), 'utf8');
    } catch (e) { }
    
    // Sub-agent details
    const subagentDetails = [];
    for (const sa of subagentSessions.slice(0, 20)) {
      const messages = await parseSessionFile(sa.path, 5);
      const firstMsg = messages.find(m => m.role === 'user');
      const lastMsg = [...messages].reverse().find(m => m.role === 'assistant');
      const isActive = sa.modified.getTime() > oneHourAgo;
      
      let task = '';
      if (firstMsg) {
        const content = typeof firstMsg.content === 'string' ? firstMsg.content :
          Array.isArray(firstMsg.content) ? firstMsg.content.map(c => c.text || '').join(' ') : '';
        task = content.substring(0, 150);
      }
      
      subagentDetails.push({
        id: sa.id.split(':').pop().substring(0, 8),
        fullId: sa.id,
        task: task,
        active: isActive,
        lastModified: sa.modified,
        size: sa.size,
      });
    }
    
    // Stats
    const totalSessions = sessions.length;
    const totalSubagents = subagentSessions.length;
    const todaysSessions = sessions.filter(s => {
      const d = s.created.toISOString().split('T')[0];
      return d === today;
    }).length;
    
    // Tools used today
    const toolCounts = {};
    for (const act of recentActivity) {
      if (act.type === 'tool_call') {
        const tool = act.tool || 'unknown';
        toolCounts[tool] = (toolCounts[tool] || 0) + 1;
      }
    }
    
    res.json({
      timestamp: new Date().toISOString(),
      buba: {
        status: activeSessions.length > 0 ? 'active' : 'idle',
        currentTask: workingState.split('\n').slice(0, 5).join('\n'),
        uptime: '24/7',
      },
      stats: {
        totalSessions,
        totalSubagents,
        activeSessions: activeSessions.length,
        activeSubagents: activeSubagents.length,
        todaysSessions,
        toolsUsedRecently: toolCounts,
      },
      subagents: subagentDetails,
      activity: recentActivity,
      workingState: workingState.substring(0, 2000),
      todayLog: todayLog.substring(0, 2000),
    });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

// API: Session detail
app.get('/api/session/:id', async (req, res) => {
  try {
    const sessionFile = path.join(SESSIONS_DIR, req.params.id + '.jsonl');
    const messages = await parseSessionFile(sessionFile, 100);
    res.json({ messages });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Buba Dashboard running at http://localhost:${PORT}`);
  console.log(`Network: http://192.168.0.25:8890`);
});
