# ssh-keygen -f /etc/ssh/ssh_host_ed25519_key
# ssh-keygen -f ~/.ssh/<name>.containers
# edit secrets file
# agenix -e secret.age

{ inputs, config, lib, pkgs, pkgs-unstable, ... }:

{
  containers = {
    nextcloud = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.71/24";
      hostBridge = "br0";
      autoStart = false;
      bindMounts = {
        "/etc/ssh/ssh_host_ed25519_key".isReadOnly = true;
        "/var/www" = {
          hostPath = "/home/wayne/dev/whd";
          isReadOnly = false;
        };
      };

      config = { config, pkgs, ... }:
      {
        networking.firewall.allowedTCPPorts = [ 80 ];

        imports = [ inputs.agenix.nixosModules.default ];

        age = {
          identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
          secrets."nextcloud" = {
            file = ../secrets/nextcloud.age;
            mode = "770";
            owner = "nextcloud";
            group = "nextcloud";
          };
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ]; # Allows all users by default. Can be [ "user1" "user2" ]
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
          };
        };

        services.nextcloud = {
          enable = true;
          package = pkgs.nextcloud30;
          hostName = "nextcloud";
          https = false;
          database.createLocally = true;
          configureRedis = true;
          autoUpdateApps.enable = true;
          maxUploadSize = "16G";
          extraAppsEnable = true;
          appstoreEnable = true;
          extraApps = with config.services.nextcloud.package.packages.apps; {
            # List of apps we want to install and are already packaged in
            # https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/nextcloud/packages/nextcloud-apps.json
            inherit calendar contacts mail notes onlyoffice tasks qownnotesapi;

            # Custom app installation example.
            # cookbook = pkgs.fetchNextcloudApp rec {
            #   url =
            #     "https://github.com/nextcloud/cookbook/releases/download/v0.10.2/Cookbook-0.10.2.tar.gz";
            #   sha256 = "sha256-XgBwUr26qW6wvqhrnhhhhcN4wkI+eXDHnNSm1HDbP6M=";
            # };
          };
          enableImagemagick = true;

          settings = {
            default_phone_region = "US";
            trusted_domains = [ "localhost" "launchpad" "192.168.1.40" "192.168.1.71" ];
          };

          config = {
            dbtype = "pgsql";
            adminuser = "nextcloud";
            adminpassFile = config.age.secrets.nextcloud.path;
          };
        };

        system.stateVersion = "24.11";
      };
    };

    livebook = {
      autoStart = false;
      privateNetwork = true;
      hostBridge = "br0";
      localAddress = "192.168.1.72/24";
      bindMounts = {
        "/etc/ssh/ssh_host_ed25519_key".isReadOnly = true;
      };

      config = { config, pkgs, ... }:
      {
        networking.firewall.allowedTCPPorts = [ 80 ];

        imports = [ inputs.agenix.nixosModules.default ];

        age = {
          identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
          secrets."whayes" = {
            file = ../secrets/whayes.age;
            mode = "770";
            owner = "wayne";
            group = "wayne";
          };
        };

        services.livebook = {
          enableUserService = true;
          environment = {
            LIVEBOOK_PORT = 20123;
            LIVEBOOK_PASSWORD = config.age.secrets.whayes.path;
          };
          # See note below about security
          environmentFile = "/var/lib/livebook.env";
          extraPackages = with pkgs; [ gcc gnumake ];
        };

        system.stateVersion = "24.11";
      };
    };

    grocy = {
      autoStart = false;
      privateNetwork = true;
      hostBridge = "br0";
      localAddress = "192.168.1.73/24";
      bindMounts = {
        "/etc/ssh/ssh_host_ed25519_key".isReadOnly = true;
      };

      config = { config, pkgs, ... }:
      {
        networking.firewall.allowedTCPPorts = [ 80 ];

        imports = [ inputs.agenix.nixosModules.default ];

        age = {
          identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
          secrets."whayes" = {
            file = ../secrets/whayes.age;
            mode = "770";
            owner = "wayne";
            group = "wayne";
          };
        };

        services.grocy = {
          enable = true;
          hostName = "grocy";
          settings = {
            currency = "USD";
            culture = "en";
          };
          nginx = {
            enableSSL = false;
          };
          phpfpm = {
            settings = {
              catch_workers_output = true;
              "listen.owner" = "nginx";
              "php_admin_flag[log_errors]" = true;
              "php_admin_value[error_log]" = "stderr";
              pm = "dynamic";
              "pm.max_children" = "32";
              "pm.max_requests" = "500";
              "pm.max_spare_servers" = "4";
              "pm.min_spare_servers" = "2";
              "pm.start_servers" = "2";
            };
          };
        };

        system.stateVersion = "24.11";
      };
    };

    onlyoffice = {
      autoStart = false;
      privateNetwork = true;
      hostBridge = "br0";
      localAddress = "192.168.1.74/24";
      bindMounts = {
        "/etc/ssh/ssh_host_ed25519_key".isReadOnly = true;
      };

      config = { config, lib, pkgs, ... }:
      {
        networking.firewall.allowedTCPPorts = [ 80 ];
        nixpkgs.config.allowUnfree = true;
        nixpkgs.config.allowUnfreePredicate = pkg:
          builtins.elem (lib.getName pkg) [ "corefonts" ];

        fonts.packages = with pkgs; [
          corefonts
        ];
        imports = [ inputs.agenix.nixosModules.default ];

        age = {
          identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
          secrets."onlyoffice" = {
            file = ../secrets/onlyoffice-jwt.age;
            mode = "770";
            owner = "onlyoffice";
            group = "onlyoffice";
          };
        };

        services.onlyoffice = {
          enable = true;
          port = 8000;
          hostname = "onlyoffice";
          package = pkgs.onlyoffice-documentserver;
          jwtSecretFile = config.age.secrets.onlyoffice.path;
          enableExampleServer = true;
          examplePort = 8001;
        };

        system.stateVersion = "24.11";
      };
    };

    laravel = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.75/24";
      hostBridge = "br0";
      autoStart = false;
      bindMounts = {
        "/var/www" = {
          hostPath = "/home/wayne/dev/laravel";
          isReadOnly = false;
        };
      };

      config = { config, pkgs, ... }:
      {
        networking = {
          firewall = {
            enable = false;
            allowedTCPPorts = [ 22 80 5173 ];
            allowedTCPPortRanges = [ { from = 8000; to = 9000; } ];
          };
          enableIPv6 = false;
          nameservers = [ "192.168.1.25" ];
          # extraHosts = ''
          #   140.82.116.6   api.github.com
          # '';
        };

        # services.nginx = {
        #   enable = false;
        #   package = pkgs.nginx;
        #   # user = "www-data";
        #   virtualHosts.localhost = {
        #     root = "/var/www/site";
        #     locations."~ \\.php$".extraConfig = ''
        #       fastcgi_pass  unix:${config.services.phpfpm.pools.mypool.socket};
        #       fastcgi_index index.php;
        #     '';
        #     locations."/robots.txt" = {
        #       extraConfig = ''
        #         rewrite ^/(.*)  $1;
        #         return 200 "User-agent: *\nDisallow: /";
        #       '';
        #     };
        #   };
        # };

        services.mysql = {
          enable = true;
          package = pkgs.mariadb;
          user = "mysql";
          # configFile = '''';
        };

        # services.phpfpm = {
        #   phpPackage = pkgs.php83;
        #   pools.mypool = {
        #     user = "nobody";
        #     settings = {
        #       "pm" = "dynamic";
        #       "listen.owner" = config.services.nginx.user;
        #       "pm.max_children" = 5;
        #       "pm.start_servers" = 2;
        #       "pm.min_spare_servers" = 1;
        #       "pm.max_spare_servers" = 3;
        #       "pm.max_requests" = 500;
        #     };
        #   };
        # };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ]; # Allows all users by default. Can be [ "user1" "user2" ]
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
          };
        };

        # programs.zsh.enable = true;
        users = {
          groups = {
            www-data = {};
            mysql = {};
          };
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" "www-data" "nginx" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [];
              # shell = pkgs.zsh;
            };
          };
        };

        programs.neovim.enable = true;
        programs.tmux = {
          enable = true;
          terminal = "tmux-256color";
          keyMode = "vi";
          shortcut = "s";
          extraConfig = ''
            set -ag terminal-overrides ",xterm-256color:RGB"
            set -g mouse on
            # Resize pane key bindings
            bind -r < resize-pane -L 5
            bind -r > resize-pane -R 5
            bind -r + resize-pane -U 5
            bind -r - resize-pane -D 5

            set-option -g status-position top
          '';
          plugins = [
            pkgs.tmuxPlugins.weather
            pkgs.tmuxPlugins.tmux-fzf
            pkgs.tmuxPlugins.resurrect
            pkgs.tmuxPlugins.nord
          ];
        };

        environment.systemPackages = with pkgs; [
          # php83 php83Packages.composer
          nodejs_22 vim git
        ];

        system.stateVersion = "24.11";
      };
    };

    mailpit = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.76/24";
      hostBridge = "br0";
      autoStart = false;
      # bindMounts = {
      #   "/var/www" = {
      #     hostPath = "/home/wayne/dev/laravel";
      #     isReadOnly = false;
      #   };
      # };

      config = { config, pkgs, pkgs-unstable, ... }:
      {
        networking.firewall = {
          enable = false;
          allowedTCPPorts = [ 1025 8025 ];
        };
        networking = {
          enableIPv6 = false;
        };

        services.nginx = {
          enable = false;
          package = pkgs.nginx;
          # user = "www-data";
          virtualHosts.localhost = {
            root = "/var/www/site";
            locations."~ \\.php$".extraConfig = ''
              fastcgi_pass  unix:${config.services.phpfpm.pools.mypool.socket};
              fastcgi_index index.php;
            '';
            locations."/robots.txt" = {
              extraConfig = ''
                rewrite ^/(.*)  $1;
                return 200 "User-agent: *\nDisallow: /";
              '';
            };
          };
        };
        # services.mailpit = {
        #   instances = {
        #     vmail = {
        #       max = 100;
        #       smtp = "127.0.0.1:1025";
        #       listen = "127.0.0.1:8025";
        #       database = "mailpit.db";
        #     };
        #   };
        # };
        _module.args.pkgs-unstable = import inputs.nixpkgs-unstable {
          inherit (pkgs.stdenv.hostPlatform) system;
          inherit (config.nixpkgs) config;
        };

        environment.systemPackages =
        (with pkgs; [
          vim
        ])

        ++
        (with pkgs-unstable; [
          mailpit
        ]);

        system.stateVersion = "24.11";
      };
    };

    webserver = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.76/24";
      hostBridge = "br0";
      autoStart = false;
      allowedDevices = [
        {
          modifier = "rw";
          node = "/dev/net/tun";
        }
      ];
      bindMounts = {
        "/var/www" = {
          hostPath = "/home/wayne/dev/www/whc/2025/dashboard";
          isReadOnly = false;
        };
        "/var/www/budget" = {
          hostPath = "/home/wayne/dev/www/whc/2025/budget";
          isReadOnly = false;
        };
        "/var/www/jose" = {
          hostPath = "/home/wayne/dev/www/jose";
          isReadOnly = false;
        };
      };
      # Testing to see if this even works
      # forwardPorts = [
      #   { hostPort = 8080; containerPort = 80; protocol = "tcp";}
      #   { hostPort = 2222; containerPort = 22; protocol = "tcp";}
      # ];

      config = { config, pkgs, pkgs-unstable, ... }:
      {
        networking.firewall = {
          enable = true;
          allowedTCPPorts = [ 22 80 443 1025 3000 3001 41641 8025 8080 2222 3306 ];
        };
        networking = {
          enableIPv6 = false;
          nameservers = [ "192.168.1.25" ];
        };

        users = {
          groups = {
            www-data = {};
            mysql = {};
            php = {};
          };
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" "www-data" "nginx" "php" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [];
            };
            php = {
              isSystemUser = true;
              group = "php";
            };
          };
        };

        services.tailscale = {
          enable = true;
          package = pkgs.tailscale;
          interfaceName = "tailscale0";
          openFirewall = true;
          port = 41641;
          useRoutingFeatures = "server";
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ]; # Allows all users by default. Can be [ "user1" "user2" ]
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
          };
        };

        # services.mysql = {
        #   enable = false;
        #   package = pkgs.mariadb;
        #   user = "mysql";
        #   # configFile = '''';
        # };

        services.nginx = {
          enable = true;
          package = pkgs.nginx;
          virtualHosts.localhost = {
            root = "/var/www";
            extraConfig = ''
              index index.html, index.php;
              '';
            #
            locations."/".extraConfig = ''
              # if ($request_method = 'OPTIONS') {
              #   add_header 'Access-Control-Allow-Origin' '*';
              #   add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
              #   add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
              #   add_header 'Access-Control-Max-Age' 1728000;
              #   add_header 'Content-Type' 'text/plain charset=UTF-8';
              #   add_header 'Content-Length' 0;
              #   return 204;
              # }

              # add_header 'Access-Control-Allow-Origin' '*';
              # add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, OPTIONS';
              # add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
              # add_header 'Accept' 'application/font-woff2;q=1.0,application/font-woff;q=0.9,*/*;q=0.8';
              index index.php index.html;
              try_files $uri $uri/ /index.php;
            '';
            locations."~ \\.php$".extraConfig = ''
              fastcgi_pass  unix:${config.services.phpfpm.pools.mypool.socket};
              fastcgi_index index.php;
              # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              # fastcgi_param APPLICATION_ENV development;
              # fastcgi_intercept_errors off;
              # fastcgi_buffer_size 16k;
              # fastcgi_buffers 4 16k;
            '';
            locations."~ \\.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map|woff|woff2)$".extraConfig = ''
                try_files $uri /index.php$request_uri;
                expires 7d;         # Cache-Control policy borrowed from `.htaccess`
            '';
            locations."/robots.txt" = {
              extraConfig = ''
                rewrite ^/(.*)  $1;
                return 200 "User-agent: *\nDisallow: /";
              '';
            };
          };
        };

        services.phpfpm = {
          phpPackage = pkgs.php83;
          pools.mypool = {
            user = "nobody";
            settings = {
              "pm" = "dynamic";
              "listen.owner" = config.services.nginx.user;
              "pm.max_children" = 32;
              "pm.start_servers" = 2;
              "pm.min_spare_servers" = 1;
              "pm.max_spare_servers" = 3;
              "pm.max_requests" = 500;
            };
          };
          phpOptions = ''
            extension=${pkgs.php83Extensions.xdebug}/lib/php/extensions/xdebug.so
          '';
          # extraConfig = ''
          # '';
        };

        _module.args.pkgs-unstable = import inputs.nixpkgs-unstable {
          inherit (pkgs.stdenv.hostPlatform) system;
          inherit (config.nixpkgs) config;
        };

        environment.systemPackages = ( with pkgs; [
          vim git
          php83 php83Extensions.xdebug
          nodejs_22 nodePackages.npm nodePackages.browser-sync
        ])

        ++
        (with pkgs-unstable; [
          mailpit
        ]);

        system.stateVersion = "24.11";
      };
    };

    glance = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.77/24";
      hostBridge = "br0";
      autoStart = false;

      config = { config, pkgs, ... }:
      {
        # networking.firewall.allowedTCPPorts = [ 80 ];
        networking = {
          firewall.enable = false;
          enableIPv6 = false;
          nameservers = [ "192.168.1.25" ];
        };

        services.glance = {
          enable = true;
          package = pkgs.glance;
          openFirewall = true;
          settings = {
            server.port = 5878;
            server.host = "0.0.0.0";
            pages = [
              {
                name = "Home";
                columns = [
                  {
                    size = "small";
                    widgets = [
                      {
                        type = "clock";
                        hour-format = "12h";
                        timezones = [
                          {
                            timezone = "America/Los_Angeles";
                            # label = "Los Angeles";
                          }
                        ];
                      }
                      {
                        type = "calendar";
                      }
                      {
                        type = "rss";
                        # limit = 10;
                        collapse-after = 3;
                        cache = "3h";
                        feeds = [
                          {
                            url = "http://rss.slashdot.org/Slashdot/slashdotMainatom";
                            title = "Slashdot";
                          }
                          {
                            url = "https://www.joshwcomeau.com/rss.xml";
                            title = "Josh Comeau";
                          }
                        ];
                      }
                      {
                        type = "rss";
                        limit = 10;
                        collapse-after = 3;
                        cache = "12h";
                        feeds = [
                          {
                            url = "https://news.un.org/feed/subscribe/en/news/topic/human-rights/feed/rss.xml";
                            title = "UN Human Rights";
                          }
                          {
                            url = "https://news.un.org/feed/subscribe/en/news/topic/humanitarian-aid/feed/rss.xml";
                            title = "UN Humanitarian Aid";
                          }
                        ];
                      }
                      {
                        type = "rss";
                        limit = 10;
                        collapse-after = 3;
                        cache = "12h";
                        feeds = [
                          {
                            url = "https://www.amnesty.org/en/feed/";
                            title = "Amnesty International";
                          }
                        ];
                      }
                      {
                        type = "rss";
                        limit = 10;
                        collapse-after = 3;
                        cache = "12h";
                        feeds = [
                          {
                            url = "https://xkcd.com/atom.xml";
                            title = "XKCD";
                          }
                        ];
                      }
                    ];
                  }
                  {
                    size = "full";
                    widgets = [
                      {
                        type = "html";
                        source = ''
                          <div class="widget-content ">
                            <h1>This</h1>
                            <p>Hello, <span class="color-primary">World</span>!</p>
                          </div>
                        '';
                      }
                      {
                        type = "hacker-news";
                      }
                      {
                        type = "reddit";
                        subreddit = "selfhosted";
                      }
                      {
                        type = "rss";
                        limit = 10;
                        collapse-after = 3;
                        cache = "4h";
                        feeds = [
                          {
                            source = "https://rss.slashdot.org/Slashdot/slashdotMainatom";
                            title = "Slashdot";
                          }
                        ];
                      }
                    ];
                  }
                  {
                    size = "small";
                    widgets = [
                      {
                        type = "search";
                        title = "Duckduckgo Search";
                        search-engine = "duckduckgo";
                        new-tab = true;
                      }
                      {
                        type = "search";
                        title = "NixOS Search";
                        search-engine = "https://search.nixos.org/packages?channel=24.11&size=50&sort=relevance&type=packages&query={QUERY}";
                        new-tab = false;
                      }
                      {
                        type = "weather";
                        units = "imperial";
                        hour-format = "12h";
                        show-area-name = true;
                        location = "Los Angeles, California, United States";
                      }
                      {
                        type = "markets";
                        markets = [
                          {
                            symbol = "BTC-USD";
                            name = "Bitcoin";
                          }
                          {
                            symbol = "XLM-USD";
                            name = "Stellar Lumens";
                          }
                          {
                            symbol = "NVDA";
                            name = "Nvidia-";
                          }
                        ];
                      }
                      {
                        type = "bookmarks";
                        groups = [
                          {
                            title = "WHD";
                            color = "200 50 50";
                            links = [
                              {
                                title = "Diaspora";
                                icon = "si:diaspora";
                                url = "https://diasporia.waynehayesdevelopment.com";
                              }
                              {
                                title = "Mastodon";
                                icon = "si:mastodon";
                                url = "https://mastodon.waynehayesdevelopment.com";
                              }
                              {
                                title = "BlueSky";
                                icon = "si:bluesky";
                                url = "https://bluesky.waynehayesdevelopment.com";
                              }
                              {
                                title = "Analytics";
                                icon = "si:matomo";
                                url = "https://analytics.waynehayesdevelopment.com";
                              }
                              {
                                title = "Cloud";
                                icon = "si:nextcloud";
                                url = "https://cloud.waynehayesdevelopment.com";
                              }
                              {
                                title = "Code";
                                icon = "si:gitea";
                                url = "https://code.waynehayesdevelopment.com";
                              }
                              {
                                title = "Wiki";
                                icon = "si:ubuntu";
                                url = "https://wiki.waynehayesdevelopment.com";
                              }
                              {
                                title = "WHD";
                                icon = "si:ubuntu";
                                url = "https://www.waynehayesdevelopment.com";
                              }
                              {
                                title = "WHC";
                                icon = "si:ubuntu";
                                url = "https://www.waynehayes.com";
                              }

                            ];
                          }
                        ];
                      }
                    ];
                  }
                ];
              }
            ];
          };
        };

        system.stateVersion = "24.11";
      };
    };

    vite = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.78/24";
      hostBridge = "br0";
      autoStart = false;
      allowedDevices = [
        {
          modifier = "rw";
          node = "/dev/net/tun";
        }
      ];
      bindMounts = {
        "/home/wayne/whc/dashboard" = {
          hostPath = "/home/wayne/dev/www/whc/2025/vite";
          isReadOnly = false;
        };
        "/home/wayne/scribevault" = {
          hostPath = "/home/wayne/dev/www/scribevault";
          isReadOnly = false;
        };
        "/home/wayne/scribevault2" = {
          hostPath = "/home/wayne/dev/www/v2-scribevault";
          isReadOnly = false;
        };
        "/home/wayne/mevn-boilerplate" = {
          hostPath = "/home/wayne/dev/www/mevn-boilerplate";
          isReadOnly = false;
        };
        "/home/wayne/aider-sv" = {
          hostPath = "/home/wayne/dev/www/aider-sv";
          isReadOnly = false;
        };
        "/home/wayne/lms-aider" = {
          hostPath = "/home/wayne/dev/www/lms-aider";
          isReadOnly = false;
        };
        "/home/wayne/stock-ticker" = {
          hostPath = "/home/wayne/dev/www/stock-ticker";
          isReadOnly = false;
        };
      };

      config = { config, pkgs,  ... }:
      {
        # networking.firewall.allowedTCPPorts = [ 80 ];
        networking = {
          firewall = {
            enable = false;
            allowedTCPPorts = [ 22 80 443 1025 5173 8025 8080 27017 ];
          };
          enableIPv6 = false;
          nameservers = [ "192.168.1.25" ];
        };

        nixpkgs.config.allowUnfree = true;

        users = {
          groups = {};
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [
                sl cowsay lolcat
              ];
            };
          };
        };

        services.tailscale = {
          enable = true;
          package = pkgs.tailscale;
          interfaceName = "tailscale0";
          openFirewall = true;
          port = 41641;
          useRoutingFeatures = "client";
        };

        services.mailpit.instances = {
          local = {
            smtp = "127.0.0.1:1025";
            losten = "127.0.0.1:8025";
            database = "mailpit.db";
          };
        };

        services.mongodb = {
          enable = true;
          package = pkgs.mongodb-ce;
          user = "mongodb";
          bind_ip = "0.0.0.0";
          dbpath = "/var/db/mongodb";
          enableAuth = false;
          pidFile = "/run/mongodb.pid";
          extraConfig = '''';
        };

        services.jenkins = {
           enable = true;
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ]; # Allows all users by default. Can be [ "user1" "user2" ]
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
          };
        };

        programs.neovim.enable = true;
        programs.tmux = {
          enable = true;
          terminal = "tmux-256color";
          keyMode = "vi";
          shortcut = "s";
          extraConfig = ''
            set -ag terminal-overrides ",xterm-256color:RGB"
            set -g mouse on
            # Resize pane key bindings
            bind -r < resize-pane -L 5
            bind -r > resize-pane -R 5
            bind -r + resize-pane -U 5
            bind -r - resize-pane -D 5

            set-option -g status-position top
          '';
          plugins = [
            pkgs.tmuxPlugins.weather
            pkgs.tmuxPlugins.tmux-fzf
            pkgs.tmuxPlugins.resurrect
            pkgs.tmuxPlugins.nord
          ];
        };

        programs.zsh = {
          enable = true;
          enableCompletion = true;
          autosuggestions.enable = true;
          syntaxHighlighting.enable = true;

          shellAliases = {};

          histSize = 10000;
          histFile = "$HOME/.zsh_history";
        };

        environment.systemPackages = ( with pkgs; [
          vim git mailpit fzf eza jq bc
          nodejs_22 nodePackages.npm nodePackages.browser-sync nodePackages.sass
          yarn nodemon
          mongodb-tools mongosh
          python312 python312Packages.pip python312Packages.pipx python312Packages.distutils
        ]);

        system.stateVersion = "24.11";
      };
    };

    node = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.79/24";
      hostBridge = "br0";
      autoStart = false;
      allowedDevices = [
        {
          modifier = "rw";
          node = "/dev/net/tun";
        }
      ];
      bindMounts = {
        "/home/wayne/node" = {
          hostPath = "/home/wayne/dev/www/maelstrom/maelstrom";
          isReadOnly = false;
        };
      };

      config = { config, pkgs, ... }:
      {
        # networking.firewall.allowedTCPPorts = [ 80 ];
        networking = {
          firewall = {
            enable = false;
            allowedTCPPorts = [ 22 80 443 1025 5173 8025 8080 ];
          };
          enableIPv6 = false;
          nameservers = [ "192.168.1.25" ];
        };

        nixpkgs.config.allowUnfree = true;
        nixpkgs.config.permittedInsecurePackages = [
          "python-2.7.18.8"
        ];

        users = {
          groups = {};
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [
                sl cowsay lolcat
              ];
            };
          };
        };

        services.tailscale = {
          enable = true;
          package = pkgs.tailscale;
          interfaceName = "tailscale0";
          openFirewall = true;
          port = 41641;
          useRoutingFeatures = "client";
        };

        services.mailpit.instances = {
          local = {
            smtp = "127.0.0.1:1025";
            losten = "127.0.0.1:8025";
            database = "mailpit.db";
          };
        };

        services.mongodb = {
          enable = true;
          package = pkgs.mongodb-ce;
          user = "mongodb";
          bind_ip = "0.0.0.0";
          dbpath = "/var/db/mongodb";
          enableAuth = false;
          pidFile = "/run/mongodb.pid";
          extraConfig = '''';
        };

        services.jenkins = {
           enable = false;
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ]; # Allows all users by default. Can be [ "user1" "user2" ]
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
          };
        };

        programs.neovim.enable = true;
        programs.tmux = {
          enable = true;
          terminal = "tmux-256color";
          keyMode = "vi";
          shortcut = "s";
          extraConfig = ''
            set -ag terminal-overrides ",xterm-256color:RGB"
            set -g mouse on
            # Resize pane key bindings
            bind -r < resize-pane -L 5
            bind -r > resize-pane -R 5
            bind -r + resize-pane -U 5
            bind -r - resize-pane -D 5

            set-option -g status-position top
          '';
          plugins = [
            pkgs.tmuxPlugins.weather
            pkgs.tmuxPlugins.tmux-fzf
            pkgs.tmuxPlugins.resurrect
            pkgs.tmuxPlugins.nord
          ];
        };

        programs.zsh = {
          enable = true;
          enableCompletion = true;
          autosuggestions.enable = true;
          syntaxHighlighting.enable = true;

          shellAliases = {};

          histSize = 10000;
          histFile = "$HOME/.zsh_history";
        };

        environment.systemPackages = ( with pkgs; [
          vim git mailpit fzf eza
          nodePackages.npm nodePackages.browser-sync nodePackages.sass
          yarn nodemon
          mongodb-tools
          python312 python312Packages.pip python312Packages.pipx python312Packages.distutils
          python27Full
          xvfb-run xorg.xvfb
        ]);

        system.stateVersion = "24.11";
      };
    };

    dmp = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.90/24";
      hostBridge = "br0";
      autoStart = false;
      allowedDevices = [
        {
          modifier = "rw";
          node = "/dev/net/tun";
        }
      ];
      bindMounts = {
        "/home/wayne/DMP" = {
          hostPath = "/home/wayne/dev/whd/DMP/";
          isReadOnly = false;
        };
      };

      config = { config, pkgs,  ... }:
      {
        # networking.firewall.allowedTCPPorts = [ 80 ];
        networking = {
          firewall = {
            enable = false;
            allowedTCPPorts = [ 22 80 443 1025 5173 8025 8080 27017 ];
          };
          enableIPv6 = false;
          nameservers = [ "192.168.1.1" ];
        };

        nixpkgs.config.allowUnfree = true;

        users = {
          groups = {};
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [
                sl cowsay lolcat
              ];
            };
          };
        };

        services.tailscale = {
          enable = false;
          package = pkgs.tailscale;
          interfaceName = "tailscale0";
          openFirewall = true;
          port = 41641;
          useRoutingFeatures = "client";
        };

        services.mailpit.instances = {
          local = {
            smtp = "127.0.0.1:1025";
            listen = "127.0.0.1:8025";
            database = "mailpit.db";
          };
        };

        services.mongodb = {
          enable = true;
          package = pkgs.mongodb-ce;
          user = "mongodb";
          bind_ip = "0.0.0.0";
          dbpath = "/var/db/mongodb";
          enableAuth = false;
          pidFile = "/run/mongodb.pid";
          extraConfig = '''';
        };

        services.jenkins = {
           enable = true;
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ];
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no";
          };
        };

        # Configure bash globally
        programs.bash = {
          completion = {
            enable = true;
            package = pkgs.bash-completion;
          };
          enableLsColors = true;
          # Global bash configuration that applies to all users
          shellInit = ''
            # Ensure .bashrc is sourced for all bash sessions
            if [ -f ~/.bashrc ]; then
              source ~/.bashrc
            fi
          '';
          # Global aliases and functions
          shellAliases = {
            ll = "ls -alF";
            la = "ls -A";
            l = "ls -CF";
            grep = "grep --color=auto";
            fgrep = "fgrep --color=auto";
            egrep = "egrep --color=auto";
          };
        };

        programs.neovim.enable = true;
        programs.tmux = {
          enable = true;
          terminal = "tmux-256color";
          keyMode = "vi";
          shortcut = "s";
          extraConfig = ''
            set -ag terminal-overrides ",xterm-256color:RGB"
            set -g mouse on
            # Resize pane key bindings
            bind -r < resize-pane -L 5
            bind -r > resize-pane -R 5
            bind -r + resize-pane -U 5
            bind -r - resize-pane -D 5

            set-option -g status-position top
          '';
          plugins = [
            pkgs.tmuxPlugins.weather
            pkgs.tmuxPlugins.tmux-fzf
            pkgs.tmuxPlugins.resurrect
            pkgs.tmuxPlugins.nord
          ];
        };

        programs.zsh = {
          enable = true;
          enableCompletion = true;
          autosuggestions.enable = true;
          syntaxHighlighting.enable = true;

          shellAliases = {};

          histSize = 10000;
          histFile = "$HOME/.zsh_history";
        };

        # Ensure bash completion is available
        environment.pathsToLink = [ "/share/bash-completion" ];

        environment.systemPackages = ( with pkgs; [
          vim git mailpit fzf eza jq bc
          nodejs_22 nodePackages.npm nodePackages.browser-sync nodePackages.sass
          yarn nodemon
          mongodb-tools mongosh
          python312 python312Packages.pip python312Packages.pipx python312Packages.distutils
          # Add bash-completion for better bash experience
          bash-completion
        ]);

        system.stateVersion = "24.11";
      };
    };

    docs = {
      privateNetwork = true;
      hostAddress = "192.168.1.40";
      localAddress = "192.168.1.91/
      0.24";
      hostBridge = "br0";
      autoStart = false;
      allowedDevices = [
        {
          modifier = "rw";
          node = "/dev/net/tun";
        }
      ];
      bindMounts = {
        "/home/wayne/docs/dmp" = {
          hostPath = "/home/wayne/dev/whd/WHD 2024 docs/DMP/";
          isReadOnly = false;
        };
      };

      config = { config, pkgs,  ... }:
      {
        # networking.firewall.allowedTCPPorts = [ 80 ];
        networking = {
          firewall = {
            enable = false;
            allowedTCPPorts = [ 22 80 443 1025 5173 8025 8080 27017 ];
          };
          enableIPv6 = false;
          nameservers = [ "192.168.1.1" ];
        };

        nixpkgs.config.allowUnfree = true;

        users = {
          groups = {};
          users = {
            wayne = {
              isNormalUser = true;
              description = "Wayne Hayes";
              extraGroups = [ "networkmanager" "wheel" "wayne" ];
              openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6q75AXShVjzWerPFU3l0YXIKViNF4eyragL+RQIRwdNDMzW34GgxFhtyLsmRB2jsykf4gx76zSyJoii0K4uhS761w5oDXz9mqHnBzJutDTyltLyfgLsFKY8V2sOtSracWx4y6QrtmBR3MKV642kg5mufVEmCMVxBU9oVpIOJUSW+XNYBawaSkl5SjDMLI7flj0v9Hb2dZqjQigDM1+UHxTzcMoZnR6hAzoZpPNMGyZXtrgEotNywNdpxCqRV9T/KvKHSIVYc1umiDXc+5fyRo9v7CzvYY3MvRKWbgUfTVQRmR2kqwsGAsV5W+PEUb8qqmTjPVXusKxKlpGgYfsvIZOv0LgOvQMemga8psFIS9F4YQ1xuc092bKi1LteC+ZlabMLRMux6Wbhjci+v9wnLfTyBQc6wr3wDFJoELKyaLnI7Cn0KHn0k+BiYCCr2TjKrz9XztL490vprYtvVumNFZ3rxewGnZSn/2czaFfQgnXt+9xQGWWo9TJGE5jq1jThnsIbH3G9JIQ1WhomMq6DDRhGMX2ZKDk/M9/fk0XN5nvQyJNmbiHy5srW/VANx8R9jjsVkvX29MXeK6dzpR4ImywXggpYMeHB6moy06cJUu5WoR8aLS/rO5LbZM2j14AMQ2ZK79QfUJSdloA1/HHlmnx7YtzZOebD6BCR7xgasGRw== wayne"];
              packages = with pkgs; [
                sl cowsay lolcat
              ];
            };
          };
        };

        services.tailscale = {
          enable = false;
          package = pkgs.tailscale;
          interfaceName = "tailscale0";
          openFirewall = true;
          port = 41641;
          useRoutingFeatures = "client";
        };

        services.openssh = {
          enable = true;
          ports = [ 22 ];
          settings = {
            PasswordAuthentication = true;
            AllowUsers = [ "wayne" ];
            UseDns = true;
            X11Forwarding = false;
            PermitRootLogin = "no";
          };
        };

        programs.neovim.enable = true;
        programs.tmux = {
          enable = true;
          terminal = "tmux-256color";
          keyMode = "vi";
          shortcut = "s";
          extraConfig = ''
            set -ag terminal-overrides ",xterm-256color:RGB"
            set -g mouse on
            # Resize pane key bindings
            bind -r < resize-pane -L 5
            bind -r > resize-pane -R 5
            bind -r + resize-pane -U 5
            bind -r - resize-pane -D 5

            set-option -g status-position top
          '';
          plugins = [
            pkgs.tmuxPlugins.weather
            pkgs.tmuxPlugins.tmux-fzf
            pkgs.tmuxPlugins.resurrect
            pkgs.tmuxPlugins.nord
          ];
        };

        programs.zsh = {
          enable = true;
          enableCompletion = true;
          autosuggestions.enable = true;
          syntaxHighlighting.enable = true;

          shellAliases = {};

          histSize = 10000;
          histFile = "$HOME/.zsh_history";
        };

        environment.systemPackages = ( with pkgs; [
          vim git mailpit fzf eza jq bc
          nodejs_22 nodePackages.npm nodePackages.browser-sync nodePackages.sass
          yarn nodemon
          mongodb-tools mongosh
          python312 python312Packages.pip python312Packages.pipx python312Packages.distutils
        ]);

        system.stateVersion = "24.11";
      };
    };
  };
}