{user}: {
  lib,
  pkgs,
  config,
  ...
}:
with lib; let
  cfg = config.displays;

  renderDisplaysForHyprland = displays: (map displayHyprlandSetting (builtins.filter (d: d.enable) displays));

  displayHyprlandSetting = display:
    specificDisplay display
    + ", "
    + resToString display.resolution
    + ", "
    + positionToHyprlandString display.position
    + ", "
    + toString display.scaling
    + ", "
    + "transform,"
    + toString display.rotation;

  swaybgJob = displays: {
    Unit = {
      Description = "SwayBG";
    };
    Service = {
      ExecStart =
        "${pkgs.swaybg}/bin/swaybg "
        + concatStringsSep " " (map swaybgCmd displays);
    };
    Install = {
      WantedBy = ["graphical-session.target"];
    };
  };

  swaybgCmd = display:
    if (display.wallpaper != "")
    then "-o ${display.name} -i ${display.wallpaper} -m fill"
    else "";

  specificDisplay = display:
    if display.description == ""
    then display.name
    else "desc:" + display.description;

  positionToHyprlandString = {
    x,
    y,
  }:
    if (x == -1 || y == -1)
    then "auto"
    else toString x + "x" + toString y;

  renderDisplaysForSway = displays:
    listToAttrs (map displaySwaySetting displays);

  displaySwaySetting = display: {
    name = display.name;
    value = let
      res = display.resolution;
    in {
      mode =
        mkIf (!resUnset res)
        "${toString res.x}x${toString res.y}@${toString res.freq}Hz";
      bg = display.wallpaper + " fill";
      scale = toString display.scaling;
    };
  };

  resolutionType = types.submodule {
    options = {
      x = mkOption {
        description = "x";
        type = types.int;
        default = 0;
      };
      y = mkOption {
        description = "y";
        type = types.int;
        default = 0;
      };
      freq = mkOption {
        description = "frequency";
        type = types.int;
        default = 0;
      };
    };
  };

  displayType = types.submodule {
    options = {
      enable = mkEnableOption "enable this display";
      name = mkOption {
        description = "name of the display";
        default = "";
      };
      description = mkOption {
        description = "description of display from hyprctl monitors";
        default = "";
      };
      scaling = mkOption {
        type = types.float;
        default = 1.0;
      };
      rotation = mkOption {
        type = types.int;
        default = 0;
      };
      resolution = mkOption {
        description = "res";
        type = resolutionType;
        default = {};
      };
      position.x = mkOption {
        default = -1;
        type = types.int;
      };
      position.y = mkOption {
        default = -1;
        type = types.int;
      };
      wallpaper = mkOption {
        description = "path to wallpaper";
        default = "";
      };
      workspaces = mkOption {
        default = {};
        type = types.submodule {
          options = {
            start = mkOption {
              type = types.int;
              default = 1;
            };
            end = mkOption {
              type = types.int;
              default = 1;
            };
          };
        };
      };
    };
  };

  resUnset = res: (res.x == 0 || res.y == 0 || res.freq == 0);

  resToString = res:
    if resUnset res
    then "preferred"
    else "${toString res.x}x${toString res.y}@${toString res.freq}";

  waybarWorkspaceConf = monitors: (map (display: {
      ${display.name} = display.workspaces.start;
    })
    monitors);

  renderWorkspacesForHyprland = displays: (map hyprWorkspaceSetting displays);
  hyprWorkspaceSetting = display:
    specificDisplay display
    + ", "
    + toString display.workspaces.start;
in {
  options.displays = {
    enable = mkEnableOption "manage displays";
    displays = mkOption {
      type = types.attrsOf displayType;
      default = {};
    };
  };

  config = mkIf cfg.enable {
    home-manager.users.${user}.imports = [
      {
        systemd.user.services.swaybg = swaybgJob (attrValues cfg.displays);

        programs.waybar.settings.mainBar."hyprland/workspaces".persistent_workspaces = waybarWorkspaceConf (attrValues cfg.displays);

        wayland.windowManager = mkIf (cfg.displays != {}) {
          hyprland.settings = {
            monitor = renderDisplaysForHyprland (attrValues cfg.displays);
            workspace = renderWorkspacesForHyprland (attrValues cfg.displays);
          };

          sway.config.output =
            renderDisplaysForSway (attrValues cfg.displays);
        };
      }
    ];
  };
}
