const express            = require('express');
const { execSync, exec } = require('child_process');
const router             = express.Router();
const authMw             = require('../middleware/auth');
const { writeAudit }     = require('./audit');

const ps = (cmd, timeout = 30000) =>
  execSync(`powershell -ExecutionPolicy Bypass -Command "${cmd}"`, { timeout }).toString().trim();

function dockerExec(args, timeout = 15000) {
  return execSync(`docker ${args}`, { timeout }).toString().trim();
}

// ── Check Docker installed ─────────────────────────────────
router.get('/status', authMw, (req, res) => {
  try {
    const version = dockerExec('--version');
    const info    = dockerExec('info --format "{{.ServerVersion}}"');
    const running = true;
    res.json({ installed: true, version, serverVersion: info, running });
  } catch {
    // Check if installed but not running
    try {
      const ver = ps(`(Get-Command docker -ErrorAction SilentlyContinue).Version`);
      res.json({ installed: !!ver, version: ver || null, running: false });
    } catch {
      res.json({ installed: false, running: false });
    }
  }
});

// ── Install Docker Desktop via Chocolatey ──────────────────
let _dockerInstallStatus = { status: 'idle' };

router.post('/install', authMw, (req, res) => {
  if (_dockerInstallStatus.status === 'running')
    return res.status(400).json({ error: 'Install already in progress' });

  _dockerInstallStatus = { status: 'running', startedAt: new Date().toISOString() };
  res.json({ ok: true, message: 'Docker Desktop installation started. This may take 10–20 minutes.' });

  const cmd = [
    `if(!(Get-Command choco -ErrorAction SilentlyContinue)){`,
    `  Set-ExecutionPolicy Bypass -Scope Process -Force;`,
    `  [Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor 3072;`,
    `  iex((New-Object Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))`,
    `}`,
    `choco install docker-desktop -y --no-progress`
  ].join(' ');

  exec(`powershell -ExecutionPolicy Bypass -Command "${cmd}"`, { timeout: 30 * 60 * 1000 }, (err) => {
    if (err) {
      _dockerInstallStatus = { status: 'error', log: err.message.substring(0, 300) };
    } else {
      _dockerInstallStatus = { status: 'done' };
      writeAudit(req, 'docker.install', 'Docker Desktop installed via Chocolatey');
    }
  });
});

router.get('/install-status', authMw, (req, res) => {
  res.json(_dockerInstallStatus);
});

// ── List containers ────────────────────────────────────────
router.get('/containers', authMw, (req, res) => {
  try {
    const raw = dockerExec('ps -a --format "{{json .}}"');
    if (!raw) return res.json([]);
    const list = raw.split('\n').filter(Boolean).map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
    res.json(list);
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── List images ───────────────────────────────────────────
router.get('/images', authMw, (req, res) => {
  try {
    const raw = dockerExec('images --format "{{json .}}"');
    if (!raw) return res.json([]);
    const list = raw.split('\n').filter(Boolean).map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
    res.json(list);
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Container actions ──────────────────────────────────────
router.post('/containers/:id/start',   authMw, (req, res) => {
  try { dockerExec(`start ${req.params.id}`);   writeAudit(req, 'docker.start',   req.params.id); res.json({ ok: true }); }
  catch(e) { res.status(500).json({ error: e.message }); }
});

router.post('/containers/:id/stop',    authMw, (req, res) => {
  try { dockerExec(`stop ${req.params.id}`);    writeAudit(req, 'docker.stop',    req.params.id); res.json({ ok: true }); }
  catch(e) { res.status(500).json({ error: e.message }); }
});

router.post('/containers/:id/restart', authMw, (req, res) => {
  try { dockerExec(`restart ${req.params.id}`); writeAudit(req, 'docker.restart', req.params.id); res.json({ ok: true }); }
  catch(e) { res.status(500).json({ error: e.message }); }
});

router.delete('/containers/:id', authMw, (req, res) => {
  try { dockerExec(`rm -f ${req.params.id}`);   writeAudit(req, 'docker.remove',  req.params.id); res.json({ ok: true }); }
  catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Pull image ─────────────────────────────────────────────
router.post('/images/pull', authMw, (req, res) => {
  const { image } = req.body;
  if (!image || !/^[\w./:@\-]+$/.test(image)) return res.status(400).json({ error: 'Invalid image name' });
  res.json({ ok: true, message: `Pulling ${image} in background...` });
  exec(`docker pull ${image}`, { timeout: 10 * 60 * 1000 }, (err) => {
    if (err) console.error('[docker/pull]', err.message);
    else writeAudit(req, 'docker.pull', image);
  });
});

// ── Remove image ───────────────────────────────────────────
router.delete('/images/:id', authMw, (req, res) => {
  try { dockerExec(`rmi ${req.params.id}`); writeAudit(req, 'docker.rmi', req.params.id); res.json({ ok: true }); }
  catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Container logs ─────────────────────────────────────────
router.get('/containers/:id/logs', authMw, (req, res) => {
  try {
    const lines = req.query.lines || 100;
    const logs  = dockerExec(`logs --tail ${lines} ${req.params.id}`);
    res.json({ logs });
  } catch(e) { res.status(500).json({ error: e.message }); }
});

// ── Run new container ──────────────────────────────────────
router.post('/containers/run', authMw, (req, res) => {
  const { image, name, ports, env, detach } = req.body;
  if (!image) return res.status(400).json({ error: 'Image is required' });
  try {
    const nameArg  = name   ? `--name ${name}` : '';
    const portArgs = (ports || []).map(p => `-p ${p}`).join(' ');
    const envArgs  = (env   || []).map(e => `--env ${e}`).join(' ');
    const detachArg= detach !== false ? '-d' : '';
    const out = dockerExec(`run ${detachArg} ${nameArg} ${portArgs} ${envArgs} ${image}`, 30000);
    writeAudit(req, 'docker.run', `${image} → ${name || out.substring(0,12)}`);
    res.json({ ok: true, containerId: out });
  } catch(e) { res.status(500).json({ error: e.message }); }
});

module.exports = router;