import express from 'express';
import http from 'node:http';

const router = express.Router();

const DOCKER_SOCKET   = '/var/run/docker.sock';
const COMPOSE_PROJECT = (process.env.DOCKER_NETWORK || 'wild-dragon_wild-dragon').split('_')[0];

function dockerGet(path) {
  return new Promise((resolve, reject) => {
    const req = http.request(
      { socketPath: DOCKER_SOCKET, path, method: 'GET' },
      (res) => {
        let data = '';
        res.on('data', chunk => { data += chunk; });
        res.on('end', () => {
          try { resolve({ status: res.statusCode, body: JSON.parse(data) }); }
          catch { resolve({ status: res.statusCode, body: data }); }
        });
      }
    );
    req.on('error', reject);
    req.end();
  });
}

function dockerPost(path) {
  return new Promise((resolve, reject) => {
    const req = http.request(
      { socketPath: DOCKER_SOCKET, path, method: 'POST', headers: { 'Content-Length': '0' } },
      (res) => {
        res.resume();
        res.on('end', () => resolve({ status: res.statusCode }));
      }
    );
    req.on('error', reject);
    req.end();
  });
}

// GET /containers – list containers for this compose project
router.get('/containers', async (req, res, next) => {
  try {
    const r = await dockerGet('/containers/json?all=1');
    if (r.status !== 200) return res.status(502).json({ error: 'Docker API error', code: r.status });

    const containers = r.body
      .filter(c => {
        const labels = c.Labels || {};
        // Match by compose project label; fall back to network name
        if (labels['com.docker.compose.project'] === COMPOSE_PROJECT) return true;
        return Object.keys(c.NetworkSettings?.Networks || {}).some(n => n.includes(COMPOSE_PROJECT));
      })
      .map(c => ({
        id:      c.Id.slice(0, 12),
        name:    (c.Names[0] || '').replace(/^\//, ''),
        image:   c.Image,
        state:   c.State,
        status:  c.Status,
        created: c.Created,
        service: (c.Labels || {})['com.docker.compose.service'] || '',
        ports:   (c.Ports || [])
          .filter(p => p.PublicPort)
          .map(p => `${p.PublicPort}:${p.PrivatePort}/${p.Type}`)
          .join(', '),
      }));

    res.json(containers);
  } catch (err) { next(err); }
});

// POST /containers/:id/restart
router.post('/containers/:id/restart', async (req, res, next) => {
  try {
    const r = await dockerPost(`/containers/${req.params.id}/restart`);
    if (r.status !== 204) return res.status(502).json({ error: 'Failed to restart', code: r.status });
    res.json({ ok: true });
  } catch (err) { next(err); }
});

// POST /containers/:id/stop
router.post('/containers/:id/stop', async (req, res, next) => {
  try {
    const r = await dockerPost(`/containers/${req.params.id}/stop`);
    if (r.status !== 204 && r.status !== 304) return res.status(502).json({ error: 'Failed to stop', code: r.status });
    res.json({ ok: true });
  } catch (err) { next(err); }
});

// POST /containers/:id/start
router.post('/containers/:id/start', async (req, res, next) => {
  try {
    const r = await dockerPost(`/containers/${req.params.id}/start`);
    if (r.status !== 204 && r.status !== 304) return res.status(502).json({ error: 'Failed to start', code: r.status });
    res.json({ ok: true });
  } catch (err) { next(err); }
});

export default router;
