const express = require('express');
const { success } = require('../src/utils/responses');
const { ValidationError } = require('../src/utilities/errors');

/**
 * Docker resources route factory (volumes, networks, disk usage)
 * @param {Object} deps
 * @param {Object} deps.docker - Docker client wrapper
 * @param {Function} deps.asyncHandler - Async route handler wrapper
 * @returns {express.Router}
 */
module.exports = function({ docker, asyncHandler }) {
  const router = express.Router();

  // ===== VOLUMES =====

  router.get('/volumes', asyncHandler(async (req, res) => {
    const result = await docker.client.listVolumes();
    const volumes = (result.Volumes || []).map(v => ({
      name: v.Name,
      driver: v.Driver,
      mountpoint: v.Mountpoint,
      scope: v.Scope,
      created: v.CreatedAt,
      labels: v.Labels || {},
    }));
    success(res, { volumes, count: volumes.length });
  }, 'docker-volumes-list'));

  router.post('/volumes', asyncHandler(async (req, res) => {
    const { name, driver } = req.body;
    if (!name || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(name)) {
      throw new ValidationError('Invalid volume name');
    }
    const volume = await docker.client.createVolume({
      Name: name,
      Driver: driver || 'local',
    });
    success(res, { message: `Volume "${name}" created`, volume: { name: volume.name } });
  }, 'docker-volumes-create'));

  router.delete('/volumes/:name', asyncHandler(async (req, res) => {
    const volume = docker.client.getVolume(req.params.name);
    await volume.remove({ force: req.query.force === 'true' });
    success(res, { message: `Volume "${req.params.name}" removed` });
  }, 'docker-volumes-delete'));

  // ===== NETWORKS =====

  router.get('/networks', asyncHandler(async (req, res) => {
    const networkList = await docker.client.listNetworks();
    const networks = networkList.map(n => ({
      id: n.Id.substring(0, 12),
      name: n.Name,
      driver: n.Driver,
      scope: n.Scope,
      internal: n.Internal,
      containers: Object.keys(n.Containers || {}).length,
      created: n.Created,
    }));
    success(res, { networks, count: networks.length });
  }, 'docker-networks-list'));

  router.post('/networks', asyncHandler(async (req, res) => {
    const { name, driver } = req.body;
    if (!name || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,63}$/.test(name)) {
      throw new ValidationError('Invalid network name');
    }
    const network = await docker.client.createNetwork({
      Name: name,
      Driver: driver || 'bridge',
    });
    success(res, { message: `Network "${name}" created`, id: network.id });
  }, 'docker-networks-create'));

  router.delete('/networks/:id', asyncHandler(async (req, res) => {
    const network = docker.client.getNetwork(req.params.id);
    await network.remove();
    success(res, { message: 'Network removed' });
  }, 'docker-networks-delete'));

  // ===== DISK USAGE =====

  router.get('/disk-usage', asyncHandler(async (req, res) => {
    const df = await docker.client.df();
    const summary = {
      images: {
        count: (df.Images || []).length,
        size: (df.Images || []).reduce((sum, i) => sum + (i.Size || 0), 0),
        reclaimable: (df.Images || []).filter(i => i.Containers === 0).reduce((sum, i) => sum + (i.Size || 0), 0),
      },
      containers: {
        count: (df.Containers || []).length,
        running: (df.Containers || []).filter(c => c.State === 'running').length,
        size: (df.Containers || []).reduce((sum, c) => sum + (c.SizeRw || 0), 0),
      },
      volumes: {
        count: (df.Volumes || []).length,
        size: (df.Volumes || []).reduce((sum, v) => sum + (v.UsageData?.Size || 0), 0),
        reclaimable: (df.Volumes || []).filter(v => v.UsageData?.RefCount === 0).reduce((sum, v) => sum + (v.UsageData?.Size || 0), 0),
      },
      buildCache: {
        count: (df.BuildCache || []).length,
        size: (df.BuildCache || []).reduce((sum, b) => sum + (b.Size || 0), 0),
        reclaimable: (df.BuildCache || []).filter(b => !b.InUse).reduce((sum, b) => sum + (b.Size || 0), 0),
      },
    };
    summary.totalSize = summary.images.size + summary.containers.size + summary.volumes.size + summary.buildCache.size;
    success(res, summary);
  }, 'docker-disk-usage'));

  return router;
};
