/**
 * Misc routes — /api/version, /api/undo, /api/memory, /api/health, /api/templates, /api/sync, /api/git
 */
import fs from 'fs';
import path from 'path';
import { exec, spawn } from 'child_process';
import { fileURLToPath } from 'url';
import { APP_VERSION } from '../../utils/config.js';

export function setupMiscRoutes(app, server) {
  // --- Health check ---
  app.get('/api/health', (req, res) => {
    const mem = process.memoryUsage();
    res.json({
      ok: true,
      status: server.isBusy() ? 'busy' : 'idle',
      uptime: Math.round(process.uptime()),
      activeSessions: server.sessionPool._sessions.size,
      memoryMB: Math.round(mem.heapUsed / 1024 / 1024),
      pid: process.pid,
      ts: Date.now(),
    });
  });

  // --- Version ---
  app.get('/api/version', (req, res) => {
    res.json({ version: APP_VERSION });
  });

  // --- Undo ---
  app.post('/api/undo', async (req, res) => {
    const stack = server.config._undoStack || [];
    if (stack.length === 0) return res.json({ ok: false, error: 'Nothing to undo' });
    const entry = stack.pop();
    try {
      await fs.promises.writeFile(entry.path, entry.content, 'utf-8');
      res.json({ ok: true, path: entry.path });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  app.get('/api/undo/stack', (req, res) => {
    const stack = server.config._undoStack || [];
    res.json(stack.map(e => ({ path: e.path, timestamp: e.timestamp })));
  });

  // --- Memory ---
  app.get('/api/memory', (req, res) => {
    try {
      const memDir = path.join(server.config.workDir, '.vl-code', 'memory');
      if (!fs.existsSync(memDir)) return res.json([]);
      const files = fs.readdirSync(memDir).filter(f => f.endsWith('.md') || f.endsWith('.json'));
      const memories = files.map(f => {
        try {
          return { name: f, content: fs.readFileSync(path.join(memDir, f), 'utf-8') };
        } catch { return null; }
      }).filter(Boolean);
      res.json(memories);
    } catch { res.json([]); }
  });

  // --- Git ---
  app.get('/api/git/status', (_req, res) => {
    exec('git status --porcelain', { cwd: server.config.workDir }, (err, stdout) => {
      if (err) return res.json({ error: 'Not a git repository', files: [] });
      const files = stdout.trim().split('\n').filter(Boolean).map(line => ({
        status: line.substring(0, 2).trim(),
        path: line.substring(3),
      }));
      res.json({ files });
    });
  });

  app.post('/api/git/commit', (req, res) => {
    const { message } = req.body;
    if (!message) return res.status(400).json({ error: 'message required' });
    exec(`git add -A && git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: server.config.workDir }, (err, stdout) => {
      if (err) return res.status(500).json({ error: err.message });
      res.json({ ok: true, output: stdout });
    });
  });

  // --- Templates ---
  app.get('/api/templates', (req, res) => {
    try {
      const tplDir = path.join(server.config.workDir, '.vl-code', 'templates');
      if (!fs.existsSync(tplDir)) return res.json([]);
      const files = fs.readdirSync(tplDir).filter(f => f.endsWith('.json'));
      res.json(files.map(f => {
        try {
          const data = JSON.parse(fs.readFileSync(path.join(tplDir, f), 'utf-8'));
          return { id: f.replace('.json', ''), name: data.name || f, description: data.description || '', ...data };
        } catch { return null; }
      }).filter(Boolean));
    } catch { res.json([]); }
  });

  app.post('/api/templates/create', async (req, res) => {
    try {
      const tplDir = path.join(server.config.workDir, '.vl-code', 'templates');
      if (!fs.existsSync(tplDir)) fs.mkdirSync(tplDir, { recursive: true });
      const id = req.body.name?.replace(/\s+/g, '-').toLowerCase() || `template-${Date.now()}`;
      fs.writeFileSync(path.join(tplDir, id + '.json'), JSON.stringify(req.body, null, 2));
      res.json({ ok: true, id });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  app.post('/api/templates/apply', async (req, res) => {
    try {
      const { id } = req.body;
      const tplPath = path.join(server.config.workDir, '.vl-code', 'templates', id + '.json');
      if (!fs.existsSync(tplPath)) return res.status(404).json({ error: 'Template not found' });
      const tpl = JSON.parse(fs.readFileSync(tplPath, 'utf-8'));
      let written = 0;
      if (tpl.files) {
        for (const f of tpl.files) {
          const fullPath = path.resolve(server.config.workDir, f.path);
          const dir = path.dirname(fullPath);
          if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
          fs.writeFileSync(fullPath, f.content || '', 'utf-8');
          written++;
        }
      }
      await server.projectContext.load();
      server.broadcast({ type: 'file_tree_updated' });
      res.json({ ok: true, written });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  app.delete('/api/templates/:id', (req, res) => {
    const fp = path.join(server.config.workDir, '.vl-code', 'templates', req.params.id + '.json');
    if (fs.existsSync(fp)) { fs.unlinkSync(fp); res.json({ ok: true }); }
    else res.status(404).json({ error: 'Not found' });
  });

  // --- Sync (instance-to-instance, kept for compatibility but simplified) ---
  app.post('/api/sync/push', async (req, res) => {
    res.json({ ok: false, error: 'Sync not available in Lite mode' });
  });

  app.post('/api/sync/pull', async (req, res) => {
    res.json({ ok: false, error: 'Sync not available in Lite mode' });
  });

  app.get('/api/sync/status', (req, res) => {
    res.json({ available: false });
  });

  // --- Restart backend ---
  app.post('/api/restart', (req, res) => {
    res.json({ ok: true, message: 'Restarting...' });
    setTimeout(() => {
      const entry = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../bin/vlcode-lite.js');
      const args = ['--web', '--port', String(server.config.port || 3300)];
      const child = spawn(process.execPath, [entry, ...args], {
        detached: true,
        stdio: 'ignore',
        cwd: process.cwd(),
        env: { ...process.env },
      });
      child.unref();
      process.exit(0);
    }, 300);
  });

  // --- Detail log clear ---
  app.delete('/api/detail-log', (req, res) => {
    res.json({ ok: true });
  });
}
