{ config, pkgs, ... }:

let
  homedir = "/home/cspark";
in
{
  # Home Manager needs a bit of information about you and the paths it should
  # manage.
  home.username = "cspark";
  home.homeDirectory = "${homedir}";

  # This value determines the Home Manager release that your configuration is
  # compatible with. This helps avoid breakage when a new Home Manager release
  # introduces backwards incompatible changes.
  #
  # You should not change this value, even if you update Home Manager. If you do
  # want to update the value, then make sure to first check the Home Manager
  # release notes.
  home.stateVersion = "23.11"; # Please read the comment before changing.

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # The home.packages option allows you to install Nix packages into your
  # environment.
  home.packages = with pkgs; [
    # # Adds the 'hello' command to your environment. It prints a friendly
    # # "Hello, world!" when run.
    # pkgs.hello

    # # It is sometimes useful to fine-tune packages, for example, by applying
    # # overrides. You can do that directly here, just don't forget the
    # # parentheses. Maybe you want to install Nerd Fonts with a limited number of
    # # fonts?
    # (nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })

    # # You can also create simple shell scripts directly inside your
    # # configuration. For example, this adds a command 'my-hello' to your
    # # environment:
    # (writeShellScriptBin "my-hello" ''
    #   echo "Hello, ${config.home.username}!"
    # '')

    # Scripts to bind/unbind usbkey from usbip server
    (pkgs.writeShellScriptBin "usbip_usbkey_bind" ''
    USBKEYBUSID="$(echo `grep 0930 /sys/bus/usb/devices/*/idVendor | cut -d '/' -f 6`)"
    sudo usbip bind -b $USBKEYBUSID
    '')
    (pkgs.writeShellScriptBin "usbip_usbkey_unbind" ''
    USBKEYBUSID="$(echo `grep 0930 /sys/bus/usb/devices/*/idVendor | cut -d '/' -f 6`)"
    sudo usbip unbind -b $USBKEYBUSID
    '')

    # Scripts to replace user utils with ones that can interface with the neovim inbuilt terminal
    (pkgs.writeShellScriptBin "cd-nvim" ''
if [ "$1" ]; then
	builtin cd "''$(realpath "$1")" && printf "\033]7;file://''${PWD}\033\\"
else
	builtin cd "''${HOME}" && printf "\033]7;file://''${PWD}\033\\"
fi
    '')
    
    # wineWowPackages.full
    # native wayland support (unstable)
    wineWowPackages.waylandFull

    firefox
    librewolf
    ungoogled-chromium
    # nyxt
    qutebrowser
    # emacs-gtk
    telegram-desktop
    #(discord.override {
    #   # remove any overrides that you don't want
    #   withOpenASAR = true;
    #   withVencord = true;
    #})
    (vesktop.override { withSystemVencord = false; }) # Discord Client Alternative
    discordo # Discord terminal client
    element-desktop
    # cinny-desktop

    lutris
    protonup-qt
    qpwgraph

    ardour
    rnnoise-plugin
    lsp-plugins
    yabridge
    yabridgectl

    MIDIVisualizer
    kdenlive
    vlc
    unityhub
    veracrypt
    boxbuddy
    distrobox
    qdirstat
    kid3
    # brasero
    # kdePackages.k3b
    # xfce.xfburn
    ffmpeg
    ventoy-full
    qbittorrent
    krita
    gimp
    
    mpdcron
    
    pass-wayland
    thunderbird
    protonmail-desktop

    ripgrep
    yazi
    ncdu
    
    # Just for utils
    pulseaudio
    alsa-utils
    
    # For curl scripts
    jq
    libnotify
  ];

  # Home Manager is pretty good at managing dotfiles. The primary way to manage
  # plain files is through 'home.file'.
  home.file = {
    # # Building this configuration will create a copy of 'dotfiles/screenrc' in
    # # the Nix store. Activating the configuration will then make '~/.screenrc' a
    # # symlink to the Nix store copy.
    # ".screenrc".source = dotfiles/screenrc;

    # # You can also set the file content immediately.
    # ".gradle/gradle.properties".text = ''
    #   org.gradle.console=verbose
    #   org.gradle.daemon.idletimeout=3600000
    # '';
    #  ".local/share/applications/ncmpcpp.desktop".text = ''
    #    [Desktop Entry]
    #    Name=NCMPCPP
    #    Comment=Run ncurses music player CPP
    #    Categories=Other;
    #    Icon=konsole
    #    Type=Application
    #    Exec=konsole -e ncmpcpp
    #    Terminal=false
    #  '';

    # Inputrc file for VI mode
    ".inputrc".source = ./global-resources/home-manager/.inputrc;
    
    # Global Wallpapers
    "Pictures/Wallpapers".source = ./global-resources/home-manager/Pictures/Wallpapers;

    # MPDCRON Configuration
    ".mpdcron/mpdcron.conf".source = ./global-resources/home-manager/.mpdcron/mpdcron.conf;
    ".mpdcron/hooks/player".source = ./global-resources/home-manager/.mpdcron/hooks/player;
  };

  # Have to enable the mpd and mpd-discord-rpc user services manually for now
  services.mpd = {
    enable = true;
    musicDirectory = "${homedir}/Spool2_Secret/Music/Flac";
    network.startWhenNeeded = true;
    extraConfig = ''
      audio_output {
        type "pipewire"
        name "PipeWire Output"
      }
    '';
  };
  services.mpd-discord-rpc.enable = true;
  programs.ncmpcpp.enable = true;

  # Home Manager is pretty good at managing dotfiles. The primary way to manage
  # plain files is through 'home.file'.
  home.file = {
    # # Building this configuration will create a copy of 'dotfiles/screenrc' in
    # # the Nix store. Activating the configuration will then make '~/.screenrc' a
    # # symlink to the Nix store copy.
    # ".screenrc".source = dotfiles/screenrc;

    # # You can also set the file content immediately.
    # ".gradle/gradle.properties".text = ''
    #   org.gradle.console=verbose
    #   org.gradle.daemon.idletimeout=3600000
    # '';
      ".local/share/applications/ncmpcpp.desktop".source = ./global-resources/home-manager/.local/share/applications/ncmpcpp.desktop; 
      ".local/share/applications/yazi.desktop".source = ./global-resources/home-manager/.local/share/applications/yazi.desktop; 
      ".local/share/applications/vieb.desktop".source = ./global-resources/home-manager/.local/share/applications/vieb.desktop; 
      ".local/share/applications/arch-nyxt-gstfix.desktop".source = ./global-resources/home-manager/.local/share/applications/arch-nyxt-gstfix.desktop; 
      ".local/share/applications/arch-nyxt-run-gstfix.sh".source = ./global-resources/home-manager/.local/share/applications/arch-nyxt-run-gstfix.sh; 
  };

  # Emacs Config Init Service
  systemd.user.services.emacs-config-initialiser = let
    script = pkgs.writeShellScript "emacs-config-initialiser-script"
      ''
      if [[ ! -d $HOME/.emacs.d ]]; then
        mkdir -p $HOME/.emacs.d
        git clone https://git.cspark.dev/cspark/Emacs-Configuration $HOME/.emacs.d
      else
        exit 0
      fi
      '';
  in
  {
    Unit = {
      Description = "Initialises default emacs configuration if not available";
    };
    Service = {
      ExecStart = "${script}"; 
    };
    Install = {
      WantedBy = [ "default.target" ];
    };
  };

  # Neovim Config Init Service
  systemd.user.services.neovim-config-initialiser = let
    script = pkgs.writeShellScript "neovim-config-initialiser-script"
      ''
      if [[ ! -d $HOME/.config/nvim ]]; then
        mkdir -p $HOME/.config/nvim
        git clone https://git.cspark.dev/cspark/Neovim-Configuration $HOME/.config/nvim
      else
        exit 0
      fi
      '';
  in
  {
    Unit = {
      Description = "Initialises default neovim configuration if not available";
    };
    Service = {
      ExecStart = "${script}"; 
    };
    Install = {
      WantedBy = [ "default.target" ];
    };
  };

  # Emacs install and enable daemon/server mode. Set to use unstable pure gtk branch (From emacs-overlay)
  #services.emacs = {
  #  enable = true;
  #  package = pkgs.emacs-gtk;
  #};

  # MPDCRON to automate MPD related events, using it to automatically restart mpd-discord-rpc service to solve issues
  systemd.user.services.mpdcron = let
    script = pkgs.writeShellScript "mpdcron-script"
      ''
      mpdcron -n
      '';
  in
  {
    Unit = {
      Description = "Start MPDCRON on boot";
    };
    Service = {
      ExecStart = "${script}"; 
      Environment = "PATH=${pkgs.mpdcron}/bin:${pkgs.systemd}/bin";
    };
    Install = {
      WantedBy = [ "default.target" ];
    };
  };

  # Home Manager can also manage your environment variables through
  # 'home.sessionVariables'. If you don't want to manage your shell through Home
  # Manager then you have to manually source 'hm-session-vars.sh' located at
  # either
  #
  #  ~/.nix-profile/etc/profile.d/hm-session-vars.sh
  #
  # or
  #
  #  ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
  #
  # or
  #
  #  /etc/profiles/per-user/cspark/etc/profile.d/hm-session-vars.sh
  #

  # Add custom directories to $PATH
  home.sessionPath = [
    "$HOME/.dotnet/tools"
  ];
  
  home.sessionVariables = {
    # EDITOR = "emacsclient -nw";
    EDITOR = "nvim";

    # Dotnet path not found fix
    DOTNET_ROOT = "${pkgs.dotnet-sdk}";
  };

  programs.bash = {
    enable = true;
    enableCompletion = true;
    # bashrcExtra = "fastfetch";
    initExtra = ''
      . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
      ([[ -z $(tty) ]] && nvim +terminal) || fastfetch
    '';
    shellAliases = {
    	sudo = "sudo ";
    	doas = "doas ";
    	edit = "$EDITOR";
    	cd = "source cd-nvim";
    };
  };

  programs.git = {
    enable = true;
    userName = "cspark";
    userEmail = "git@cspark.dev";
  };

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}
