{ pkgs, lib, config, ... }:

let
  cfg = config.mods;
  wg = cfg.wireguard;

in with lib; {
  options.mods = {
    i2p.enable = mkEnableOption "enables i2p network";
    tailscale.enable = mkEnableOption "enables tailscale";

    wireguard.id = mkOption {
      type = with types; nullOr ints.u8;
      default = null;
    };

    openvpn.enable = mkEnableOption "enables openvpn config";
    openvpn.config = let
      username = "${config.mods.user.name}";
      folder = "${config.users.users.${username}.home}/documents/openvpn/";
      file = "${config.mods.user.name}.ovpn";
    in mkOption {
      description = "the config location";
      default = "${folder}${file}";
    };
  };

  config = {
    networking.networkmanager.enable = true;
    # networking.nameservers = [ "45.90.28.97" "45.90.30.97" ];
    networking.nameservers = [ "194.242.2.4#base.dns.mullvad.net" ];
    # services.resolved = {
    #   enable = true;
    #   dnssec = "false";
    #   dnsovertls = "true";
    #   domains = [ "~." ];
    #   fallbackDns = [ "194.242.2.4#base.dns.mullvad.net" ];
    # };

    # udev 250 doesn't reliably reinitialize devices after restart
    systemd.services.systemd-udevd.restartIfChanged = false;
    # systemd.services.NetworkManager-wait-online.enable = lib.mkForce false;
    # systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false;

    services.tailscale.enable = cfg.tailscale.enable;

    services.openvpn.servers = mkIf cfg.openvpn.enable {
      remote.config = "config ${cfg.openvpn.config}";
    };

    networking.firewall.allowedTCPPorts = [
      7656 # default proto sam port
      7070 # default web interface port
      4447 # default socks proxy port
      4444 # default http proxy port
    ];
    services.i2pd = lib.mkIf cfg.i2p.enable {
      enable = true;
      proto.sam.enable = true;
      address = "127.0.0.1";
      proto = {
        http.enable = true;
        socksProxy.enable = true;
        httpProxy.enable = true;
      };
    };

    networking.firewall.allowedUDPPorts = [ 51820 16261 ];
    networking.wg-quick.interfaces = lib.mkIf (wg.id != null) {
      wg0 = {
        address = [
          "10.0.0.${toString wg.id}/24"
          "fdc9:281f:04d7:9ee9::${toString wg.id}/64"
        ];
        dns = [ "10.0.0.1" "fdc9:281f:04d7:9ee9::1" ];
        mtu = 1500;
        privateKeyFile = "/home/muon/wireguard-keys/private";

        peers = [{
          publicKey = "2RF8GmTZwQdzVm2l2piYy6U0qiMU3wSxC7Lt8urAjwA=";
          presharedKeyFile =
            "/home/muon/wireguard-keys/psk-${config.networking.hostName}";
          allowedIPs = [ "10.0.0.${toString wg.id}/24" ];
          # allowedIPs = [ "0.0.0.0/0" ];
          # ip route add 93.95.230.11 via 192.168.0.1
          endpoint = "93.95.230.11:51820";
          persistentKeepalive = 25;
        }];
      };
    };

    networking.extraHosts = ''
      10.0.0.1 mups
      10.0.0.2 muon
      10.0.0.3 muho
      10.0.0.4 muop
    '';

    # gateway =
    # "${pkgs.networkmanager}/bin/nmcli dev show ${interface} | ${pkgs.gnugrep}/bin/fgrep IP4.GATEWAY | ${pkgs.awk}/bin/awk {print $2}";

  };
}
