{ config, pkgs, inputs, ... }:
let
  wireguardIP = config.cos.wireguard.clientInternalIP;
  wireguardInterface = config.cos.wireguard.interface;
  sshPort = 22;
  jellyfinDataDir = "/Block/jellyfin/jellyfin-data";
  jellyfinCacheDir = "/Block/jellyfin/jellyfin-cache";
  jellyfinPort = 8096;
  hydraPort = 7839;
  nextcloudPort = 8120;
in
{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      ../cos.nix
    ];

  cos.username = "clhickey";
  cos.hostName = "nixnas";

  cos.wireguard = {
    enable = true;
    privateKeyFile = "/Block/wireguard-keys/private";
  };
  
  cos.bikeability = {
    enable = true;
    dataDir = "/Block/bikeability";
    tileserverHost = wireguardIP;
    tileserverPort = 8000;
    clientHost = wireguardIP;
    clientPort = 8001;
    openFirewall = true;
    firewallInterface = wireguardInterface;
    fetchAndRenderTimerConfig = {
      OnCalendar = "weekly";
      Persistent = true;
    };
  };

  networking = {
    firewall = {
      interfaces = {
        ${wireguardInterface} = {
          allowedTCPPorts = [
            80
            443
            sshPort
            jellyfinPort
            hydraPort
            nextcloudPort
            config.services.languini.port
          ];
          allowedUDPPorts = [
            config.networking.wireguard.interfaces.${wireguardInterface}.listenPort
          ];
        };
      };
    };
  };

  services.openssh = {
    enable = true;
    openFirewall = false;
    listenAddresses = [
      {
        addr = wireguardIP;
        port = sshPort;
      }
    ];
  };

  nixpkgs = {
    overlays = [
      (final: prev: {
        jellyfin-ffmpeg = prev.jellyfin-ffmpeg.override {
          ffmpeg_7-full = prev.ffmpeg_7-full.override {
            withUnfree = true;
          };
        };
      })
    ];
    config.allowUnfree = true;
  };

  environment.systemPackages = with pkgs; [
    inputs.cnvim.packages.x86_64-linux.default
    wget
    tilemaker
    osmium-tool
    osmctools
    mbtileserver
    git
    gh
    htop
    wireguard-tools
    fastfetch
  ];

  services.jellyfin = {
    enable = true;
    cacheDir = jellyfinCacheDir;
    dataDir = jellyfinDataDir;
  };

  services.postgresql.dataDir = "/Block/postgresql";

  services.hydra = {
    enable = true;
    hydraURL = "http://hydra.claytonhickey.me";
    notificationSender = "hydra@claytonhickey.me";
    buildMachinesFiles = [];
    useSubstitutes = true;
    listenHost = "127.0.0.1";
    port = hydraPort;
  };
  
  nix.buildMachines = [
    {
      hostName = "localhost";
      protocol = null;
      system = "x86_64-linux";
      supportedFeatures = [ "kvm" "nixos-test" "big-parallel" "benchmark" ];
      maxJobs = 4;
    }
  ];

  services.nextcloud = {
    enable = true;
    package = pkgs.nextcloud32;
    extraApps = let apps = config.services.nextcloud.package.packages.apps; in {
      contacts = apps.contacts;
      calendar = apps.calendar;
      tasks = apps.tasks;
      news = apps.news;
      notes = apps.notes;
      forms = apps.forms;
      richdocuments = apps.richdocuments;
      #onlyoffice = apps.onlyoffice;
    };
    extraAppsEnable = true;
    hostName = "nextcloud.claytondoesthings.xyz";
    https = true;
    maxUploadSize = "1G";
    config = {
      adminpassFile = "${pkgs.writeText "adminpass" "@n2XuojRT9*&e5"}";
      adminuser = "clay53";
      dbtype = "sqlite";
    };
    home = "/Block/nextcloud";
    settings = {
      log_type = "file";
      loglevel = 0;
      trusted_proxies = [
        "10.100.0.1"
      ];
      trusted_domains = [
        "${wireguardIP}:${builtins.toString nextcloudPort}"
      ];
    };
  };

  services.nginx.logError = "/var/log/nginx/error.log";
  services.nginx.recommendedProxySettings = true;
  services.nginx.virtualHosts."hydra.claytonhickey.me" = {
    locations."/".proxyPass = "http://127.0.0.1:${builtins.toString hydraPort}";
  };

  services.nginx.virtualHosts."${config.services.nextcloud.hostName}" = {
    listen = [ { addr=wireguardIP; port=nextcloudPort; } ];
  };

  services.onlyoffice = {
    enable = false;
    hostname = "localhost";
    jwtSecretFile = "/Block/onlyoffice.jwt.secret";
  };

  services.languini = {
    enable = true;
    stateDir = "/Block/languini";
    host = wireguardIP;
    port = 5267;
  };

  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  networking.hostName = "nixnas";

  networking.networkmanager.enable = true;

  time.timeZone = "America/New_York";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "en_US.UTF-8";
    LC_IDENTIFICATION = "en_US.UTF-8";
    LC_MEASUREMENT = "en_US.UTF-8";
    LC_MONETARY = "en_US.UTF-8";
    LC_NAME = "en_US.UTF-8";
    LC_NUMERIC = "en_US.UTF-8";
    LC_PAPER = "en_US.UTF-8";
    LC_TELEPHONE = "en_US.UTF-8";
    LC_TIME = "en_US.UTF-8";
  };

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "us";
    variant = "";
  };

  users.users.clhickey = {
    isNormalUser = true;
    description = "Clayton Lopez Hickey";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [];
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfAsdqom/OjlYc5+XBVQwSh3AW5o5tZriwDgD9JvYz/ clayton@claytondoesthings.xyz"
    ];
  };
  
  users.users.languini.openssh.authorizedKeys.keys = [
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfAsdqom/OjlYc5+XBVQwSh3AW5o5tZriwDgD9JvYz/ clayton@claytondoesthings.xyz"
  ];

  users.users.root.openssh.authorizedKeys.keys = [
    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfAsdqom/OjlYc5+XBVQwSh3AW5o5tZriwDgD9JvYz/ clayton@claytondoesthings.xyz"
  ];

  services.getty.autologinUser = "clhickey";

  nix.settings.secret-key-files = "/Block/keys/nix/cache-priv-key.pem";

  system.stateVersion = "25.05"; # Did you read the comment?

}
