{ pkgs, lib, ... }:

let
  homedir = builtins.getEnv "HOME";
  hostname = lib.strings.removeSuffix "\n" (builtins.readFile /etc/hostname);
  gpgid = "66A6AD150399D970DCA4C4E6C8218B7D0BFDECCD";
  cmdtree = pkgs.stdenv.mkDerivation {
    name = "cmdtree";
    src = fetchGit {
      url = "https://git.sr.ht/~jb55/cmdtree";
      ref = "master";
      rev = "5606078e8fa02462f0208d9f9cad98c7673812e6";
    };
    buildPhase = ''
      cp ${./cfg.def.h} ./cfg.def.h
      make
    '';
    installPhase = ''
      mkdir -p $out/bin
      cp ./cmdtree $out/bin
    '';
    buildInputs = [ pkgs.xorg.libX11 pkgs.xorg.libXft ];
  };

  base16-scheme = "solarized";
  base16 = pkgs.stdenv.mkDerivation {
    name = "base16-builder";
    src = builtins.fetchTarball {
      url = "https://github.com/auduchinok/base16-builder/archive/51e3ad4d447fc3f1f539d0bfe33c851728fb6b5f.tar.gz";
      sha256 = "1qir689h38c6jr7fbbqbc3029544zgv41lrrqdcq26kcwxcwjrz1";
    };
    nativeBuildInputs = [pkgs.ruby];
    buildPhase = "${pkgs.ruby}/bin/ruby base16 -s schemes/${base16-scheme}.yml";
    installPhase = ''
      mkdir -p $out
      cp -r output/* $out
    '';
  };
  theme = lib.removeSuffix "\n" (builtins.readFile "${homedir}/.local/share/xtheme");
  xresources = "${base16}/xresources/base16-${base16-scheme}.${theme}.xresources";

  # used in polybar and dunst
  colors = { # derived from spacemacs
    "dark" = {
      highlight = "#5d4d7a";
      background = "#292b2e";
      foreground = "#b2b2b2";
    };
    "light" = {
      highlight = "#67b11d";
      background = "#f6f1e1";
      foreground = "#655370";
    };
  };
  xmonadPackages = self: [
    self.xmonad-contrib
    #self.taffybar # fails to build
    self.xmonad-extras
    self.monad-logger
  ];
in
{
  imports = [
    ./common.nix
    ./email.nix
  ];
  home = {
    keyboard.options = [ "caps:ctrl_modifier" ];
    sessionVariables = {
      LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive";
    };
    file = {
      mutt = {
        text = (builtins.readFile ./muttrc) +
          (builtins.readFile ./mutt/solarized.muttrc);
        target = ".muttrc";
      };
      mailcap = {
        source = ./mailcap;
        target = ".mailcap";
      };
      xbindkeys = {
        source = ./xbindkeysrc;
        target = ".xbindkeysrc";
      };
    };

    packages = with pkgs; [
      acpi
      apvlv
      beets
      bind
      blueman
      cmdtree
      dict
      dmenu
      dolphin
      feh
      flameshot
      gajim
      gopher
      glibcLocales # rofi locale fix -- https://github.com/rycee/home-manager/issues/354#issuecomment-415914278
      gnumake
      gnupg
      gopher
      hledger-ui
      hledger-web
      # keybase-gui
      ledger
      libnotify
      lshw
      minitube
      mononoki
      mplayer
      muchsync
      mumble
      # neomutt
      obs-studio
      pamixer
      pandoc
      pasystray
      pavucontrol
      pdftk
      pinentry
      sqlite
      tdesktop
      # texlive.combined.scheme-full
      tor-browser-bundle-bin
      usbutils
      utillinux
      vlc
      xbindkeys
      xclip
      xdotool
      xlayoutdisplay
      xorg.xmodmap
      xterm
      yank
      youtube-dl
      yubioath-desktop
      zathura

      # languages i regularly use
      (haskellPackages.ghcWithPackages (a: with a; [hledger rainbow])) # for hledger scripting
      guile
      python3
    ];
  };
  fonts.fontconfig.enable = true;

  xresources = {
    properties = {
      "XTerm*font" = "-*-FiraMono-medium-r-normal--18-*-*-*-*-*-iso10646-1";
      "XTerm*faceName" = "FireMono";
      "XTerm*faceSize" = "10";
      "XTerm*termName" = "xterm-256color";
      "XTerm*metaSendsEscape" = true;
      "XTerm*utf8" = true;
      #"Xautolock.time:" = 1;
      #"Xautolock.locker:" = "xlock";
      #"Xautolock.corners:" = "+0-0";
      #"Xautolock.cornerdelay:" = 3;
      #"Xautolock.notify:" = 30;
      #"Xautolock.notifier:" = "notify-send -u critical -t 10000 -- 'Locking screen in 30 seconds'";
    };
    extraConfig = builtins.readFile(xresources);
  };

  services = {
    lorri.enable = false;
    emacs.enable = true;

    kbfs.enable = false;
    keybase.enable = false;

    mbsync = {
      enable = if hostname == "lithium" then true else false;
      frequency = "*:0/5";
      postExec = "${pkgs.notmuch}/bin/notmuch new";
    };

    mpd = {
      enable = true;
      musicDirectory = "/mnt/campbell/ben/music";
      network = {
        listenAddress = "0.0.0.0";
        port = 6600;
      };
      extraConfig = ''
        audio_output {
          type "httpd"
          name "HTTP Stream"
          encoder "vorbis"
          port "8097"
          quality "7.0"
          format "44100:16:2"
        }
      '';
    };

    polybar = {
      # https://github.com/0x746866/dots/blob/master/polybar/config
      enable = true;
      config = {
        "bar/top" = {
          background = colors."${theme}".background;
          font-0 = "FiraSans:size=16";
          font-1 = "Font Awesome 5:pixelsize=11;1";
          font-2 = "MaterialIcons:size=10:antialias=false;2";
          foreground = colors."${theme}".foreground;
          height = "30";
          module-margin = 1;
          modules-center = "date";
          modules-left = "volume-bar";
          modules-right = [ "battery" "cpu" "mem" "temp" ];
          monitor = "\${env:MONITOR:HDMI-2}";
          monitor-fallback = "\${env:MONITOR:eDP-1}";
          radius = 0;
          separator = "|";
          tray-background = colors."${theme}".background;
          tray-detached = false;
          tray-maxsize = 16;
          tray-offset-x = 0;
          tray-offset-y = 0;
          tray-padding = 0;
          tray-position = "right";
          tray-scale = 1;
          width = "100%";
        };
        "module/date" = {
          type = "internal/date";
          internal = 5;
          date = "%Y.%m.%d";
          time = "%H.%M";
          label = "%date%..%time%";
        };
        "module/battery" = {
          type = "internal/battery";
          battery = "BAT0";
          adapter = "AC";
          full-at = 99;
        };
        "module/volume-bar" = {
          type = "internal/alsa";
          master-soundcard = "hw:1";
          bar-volume-font = 2;
          bar-volume-width = 9;
          format-volume = "<label-volume><bar-volume>";
          label-volume = " .) ";
          label-muted = " .) mute";
          label-volume-foreground = colors.${theme}.foreground;
          format-muted-foreground = colors.${theme}.foreground;
          bar-volume-foreground-0 = colors.${theme}.foreground;
          bar-volume-foreground-1 = colors.${theme}.foreground;
          bar-volume-foreground-2 = colors.${theme}.foreground;
          bar-volume-foreground-3 = colors.${theme}.foreground;
          bar-volume-foreground-4 = colors.${theme}.foreground;
          bar-volume-foreground-5 = colors.${theme}.foreground;
          bar-volume-foreground-6 = colors.${theme}.foreground;
          bar-volume-gradient = true;
          bar-volume-indicator = "•";
          bar-volume-fill = "•";
          bar-volume-empty = "·";
          bar-volume-empty-foreground = colors.${theme}.foreground;
        };
        "module/ethernet" = {
          type = "internal/network";
          interface = "enp1s0";
          label-connected = "eth up: %upspeed:9% down: %downspeed%";
          label-disconnected = "no eth";
        };
        "module/wifi" = {
          type = "internal/network";
          interface = "wlan1";
          label-connected = "wifi up: %upspeed% down: %downspeed%";
          label-disconnected = "no wifi";
        };
        "module/cpu" = {
          type = "internal/cpu";
          interval = 3;
          format-padding = 1;
          format = "<label> <ramp-coreload>";
          label = " %percentage:2%%";
          ramp-coreload-0 = "▂";
          ramp-coreload-1 = "▃";
          ramp-coreload-2 = "▄";
          ramp-coreload-3 = "▅";
          ramp-coreload-4 = "▆";
          ramp-coreload-5 = "▇";
          ramp-coreload-0-foreground = colors.${theme}.foreground;
          ramp-coreload-1-foreground = colors.${theme}.foreground;
          ramp-coreload-2-foreground = colors.${theme}.foreground;
          ramp-coreload-3-foreground = colors.${theme}.foreground;
          ramp-coreload-4-foreground = colors.${theme}.foreground;
          ramp-coreload-5-foreground = colors.${theme}.highlight;
        };
        "module/temp" = {
          type = "internal/temperature";
          interval = 3;
          thermal-zone = 0;
          warn-temperature = 70;
          format = "<ramp> <label>";
          format-padding = 1;
          label = "%temperature-c%";
          ramp-0 = "_";
          ramp-1 = ".";
          ramp-2 = ":";
          ramp-3 = "|";
          ramp-4 = "!!";
          ramp-0-foreground = colors.${theme}.foreground;
          ramp-1-foreground = colors.${theme}.foreground;
          ramp-2-foreground = colors.${theme}.foreground;
          ramp-3-foreground = colors.${theme}.foreground;
          ramp-4-foreground = colors.${theme}.highlight;
          format-warn = "<label-warn>";
          label-warn = "  %temperature-c%";
          label-warn-padding = 1;
          label-warn-foreground = colors.${theme}.highlight;
        };
        "module/mem" = {
          type = "internal/memory";
          interval = 3;
          format = "<label>";
          label-padding = 1;
          label = " |[]| %percentage_used%%";
        };
      };
      script = ''
        polybar top &
      '';
    };

    dunst = {
      enable = true;
      settings = {
        global = {
          geometry = "320x5-10+30";
          transparency = 0;
          frame_color = colors."${theme}".highlight;
          frame_width = 3; # same as xmonad border
          separator_color = "frame";
          font = "Fira Sans";
          background = colors."${theme}".background;
          foreground = colors."${theme}".foreground;
          padding = 10;
          horizontal_padding = 10;
          word_wrap = "yes";
          markup = "full";
          format = "<b>%s</b>\\n%b\\n";
        };

        urgency_normal = {
          background = colors."${theme}".background;
          foreground = colors."${theme}".foreground;
          timeout = 10;
        };
      };
    };

    redshift = {
      enable = true;
      latitude = "40.80";
      longitude = "-81.52";
      temperature = {
        # orange = 1000, white = 5000
        day = 5000;
        night = 2300;
      };
    };

    random-background = {
      enable = true;
      enableXinerama = true;
      imageDirectory = "%h/wallpaper";
      interval = "5m";
    };

    gpg-agent = {
      enable = true;
      enableScDaemon = true; # smart card support
      defaultCacheTtl = 7200; # 2 hours
      maxCacheTtl = 86400; # 24 hours
      enableSshSupport = false;
      enableExtraSocket = true;
      verbose = true;
      pinentryFlavor = "curses";
      extraConfig = ''
        allow-emacs-pinentry
        # StreamLocalBindUnlink yes
        # RemoteForward /home/ben/.gnupg/S.gpg-agent /home/ben/.gnupg/S.gpg-agent.extra
      '';
    };
  };

  xsession = {
    enable = true;
    pointerCursor = {
      package = pkgs.vanilla-dmz;
      name = "Vanilla-DMZ";
    };
    windowManager = {
      xmonad = {
        enable = true;
        extraPackages = xmonadPackages;
        enableContribAndExtras = true;
        config = ./xmonad.hs;
      };
    };
  };

  programs = {
    git.signing.signByDefault = true;
    qutebrowser = {
      enable = true;
      settings = {
        "colors.webpage.darkmode.enabled" =
          if theme == "dark" then true else false;

        "content.user_stylesheets" = "~/.userstyles.css"; # generated in common.nix

        # attempting to fix gl rendering
        "qt.force_software_rendering" = "qt-quick";
        #"backend" = "webkit";
      };
    };

    chromium = {
      enable = true;
    };

    rofi = {
      enable = true;
      pass.enable = true;
      plugins = with pkgs; [
        rofi-calc
        rofi-emoji
        rofi-file-browser
        rofi-menugen
        rofi-mpd
        rofi-pass
        rofi-systemd
      ];
    };
  };

  systemd.user = {
    services = {
      #"gpg-refresh".Service.ExecStart = "${pkgs.gnupg}/bin/gpg --refresh";
      # make it the same as 'systemctl show mpd | grep LimitMEMLOCK"
      # might not be necessary?
      #mpd.Service.LimitMEMLOCK = "2085444096";
    };
    timers = {
      #"gpg-refresh" = {
      #  Install.WantedBy = ["timers.target"];
      #  Timer.OnCalendar = "daily";
      #};
    };
  };
}