{
  config,
  lib,
  nodes,
  ...
}:
with lib; let
  cfg = config.homelab.reverseProxy;
  homelabCfg = config.homelab;
  hasNodes = length (attrNames nodes) > 0;

  # Local aggregation
  localAggregation = {
    allEntries = cfg.entries;
  };

  # Global aggregation
  globalAggregation = let
    baseAgg = import ../aggregators/base.nix {inherit lib;};

    entriesAgg = baseAgg.aggregateFromNodes {
      inherit nodes;
      attributePath = "homelab.reverseProxy.allEntries";
      enhancer = entry:
        entry
        // {
          _upstream = "http://${entry.host}:${toString entry.port}";
          _fqdn = "${entry.subdomain}.${entry._nodeConfig.config.homelab.externalDomain or homelabCfg.externalDomain}";
          _internal = "${entry.host}:${toString entry.port}";
        };
    };
  in {
    allEntries = entriesAgg.all;
    entriesBySubdomain = groupBy (e: e.subdomain) entriesAgg.all;
    entriesWithAuth = entriesAgg.filterBy (e: e.enableAuth or false);
    entriesWithoutAuth = entriesAgg.filterBy (e: !(e.enableAuth or false));
    summary = {
      total = length entriesAgg.all;
      byNode = entriesAgg.countBy (e: e._nodeName);
      withAuth = length (entriesAgg.filterBy (e: e.enableAuth or false));
      withoutAuth = length (entriesAgg.filterBy (e: !(e.enableAuth or false)));
    };
  };
in {
  options.homelab.reverseProxy = {
    enable = mkEnableOption "reverse proxy system";

    entries = mkOption {
      type = types.listOf (types.submodule {
        options = {
          subdomain = mkOption {type = types.str;};
          host = mkOption {
            type = types.str;
            default = homelabCfg.hostname;
          };
          port = mkOption {type = types.port;};
          path = mkOption {
            type = types.str;
            default = "/";
          };
          enableAuth = mkOption {
            type = types.bool;
            default = false;
          };
          enableSSL = mkOption {
            type = types.bool;
            default = true;
          };
        };
      });
      default = [];
    };

    # Always exposed aggregated data
    allEntries = mkOption {
      type = types.listOf types.attrs;
      default = localAggregation.allEntries;
      readOnly = true;
    };

    global = mkOption {
      type = types.attrs;
      default = globalAggregation;
      readOnly = true;
    };
  };

  config = mkIf cfg.enable {
    # Always expose both local and global
    # homelab.reverseProxy = {
    #   allEntries = localAggregation.allEntries;
    #   global =
    #     if hasNodes
    #     then globalAggregation
    #     else {};
    # };
  };
}
