{ config, options, lib, inputs, pkgs, self, ... }:
let
  cfg = config.profiles.gui;

  neotheme = config.neotheme;
in
{
  imports = [
    ../../modules/misc/neotheme
  ];

  options.profiles.gui = {
    enable = lib.mkEnableOption
      "The gui profile, sets up sway and related applications.";

    laptop.enable = lib.mkEnableOption
      "Enable laptop-specific tweaks";

    font = {
      name = lib.mkOption {
        type = lib.types.str;
        default = "Dina";
        description = "Name of the primary font";
      };

      size = lib.mkOption {
        type = lib.types.number;
        default = 10;
        description = "Size for the primary font";
      };

      pixelSize = lib.mkOption {
        type = lib.types.number;
        default = 13;
        description = "Pixelsize(px) for the primary font";
      };
    };
  };

  config = lib.mkIf cfg.enable {
    neotheme = {
      name = "Softjelly";
      identifier = "softjelly";

      colors = {
        background = "151515";
        foreground = "cbc0ab";
        alt0 = "404040";
        alt1 = "606060";
        color0 = "3c3c3c";
        color1 = "cf6a4c";
        color2 = "99ad6a";
        color3 = "dfa358";
        color4 = "8197bf";
        color5 = "b3a3ff";
        color6 = "8fbfdc";
        color7 = "cbc0ab";
        bright0 = "4c4c4c";
        bright1 = "d98870";
        bright2 = "adbd88";
        bright3 = "e5b579";
        bright4 = "9aaccc";
        bright5 = "c2b5ff";
        bright6 = "a5cce3";
        bright7 = "d5cdbc";
      };

      gtk = {
        theme.dark = "Adwaita-dark";
        theme.light = "Adwaita";
        iconTheme.dark = "Papirus-Dark";
        iconTheme.light = "Papirus-Light";
      };
    };

    gtk.enable = true;
    gtk.iconTheme.package = pkgs.papirus-icon-theme;
    gtk.iconTheme.name = neotheme.gtk.iconTheme.dark;
    gtk.theme.package = pkgs.gnome-themes-extra;
    gtk.theme.name = neotheme.gtk.theme.dark;
    gtk.font.name = "${cfg.font.name} ${toString cfg.font.size}";

    home.file.".icons/default".source = "${pkgs.vanilla-dmz}/share/icons/Vanilla-DMZ-AA";

    home.packages = [
      # Sway
      pkgs.alsa-utils
      pkgs.autotiling
      pkgs.brightnessctl
      pkgs.blueberry
      pkgs.swaybg
      pkgs.wayland-utils
      pkgs.wl-color-picker
      pkgs.wl-clipboard
      pkgs.wl-mirror
      pkgs.grim
      pkgs.slurp
      pkgs.sway-contrib.grimshot
      pkgs.waybar
      pkgs.bemenu
      pkgs.qt5.qtwayland
      pkgs.xdg-utils

      # Fix gpg not recognizing foot terminfo
      pkgs.foot.terminfo
    ];

    home.sessionVariables = {
      NIXOS_OZONE_WL = 1; # NOTE: might cause problems with old electron
      _JAVA_AWT_WM_NONREPARENTING = 1; # Fix 'grey screen' issue on java apps
      SDL_VIDEODRIVER = "wayland";
      # TODO: https://github.com/qutebrowser/qutebrowser/discussions/7938
      QT_SCALE_FACTOR_ROUNDING_POLICY = "RoundPreferFloor";
    };

    wayland.windowManager.sway = {
      enable = true;

      package = options.wayland.windowManager.sway.package.default;

      wrapperFeatures = {
        base = true;
        gtk = true;
      };

      config = {
        bars = [{ command = "${pkgs.waybar}/bin/waybar"; }];
        keybindings = { };
      };

      extraSessionCommands = ''
        . "${config.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh"
      '';

      extraConfig = import ./config/sway.nix { inherit config pkgs neotheme; };
    };

    i18n.inputMethod.enabled = "fcitx5";
    i18n.inputMethod.fcitx5.addons = with pkgs; [
      fcitx5-gtk
      fcitx5-mozc
      fcitx5-hangul
    ];
    systemd.user.services.fcitx5-daemon.Service = {
      # HACK: fcitx5 crashes with "Wayland connection got error: 109"
      Restart = "on-failure";
    };

    programs = {
      foot = {
        enable = true;

        settings = import ./config/foot.nix { inherit config neotheme; };
      };

      waybar = {
        enable = config.wayland.windowManager.sway.enable;

        settings = [ (import ./config/waybar/settings.nix { inherit config lib pkgs neotheme; }) ];

        style = import ./config/waybar/style.nix { inherit config neotheme; };
      };
    };

    services = {
      darkman = {
        enable = true;
        settings = {
          lat = 36.5;
          lng = 127.2;
          usegeoclue = true;
        };

        darkModeScripts = {
          gtk-theme = ''
            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/color-scheme "'prefer-dark'"

            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/gtk-theme "'${neotheme.gtk.theme.dark}'"

            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/icon-theme "'${neotheme.gtk.iconTheme.dark}'"
          '';
        };
        lightModeScripts = {
          gtk-theme = ''
            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/color-scheme "'prefer-light'"

            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/gtk-theme "'${neotheme.gtk.theme.light}'"

            ${pkgs.dconf}/bin/dconf write \
              /org/gnome/desktop/interface/icon-theme "'${neotheme.gtk.iconTheme.light}'"
          '';
        };
      };

      kanshi = {
        enable = true;
        settings = [
          {
            profile.name = "haruka-standalone";
            profile.outputs = [
              {
                criteria = "AU Optronics 0xD291 Unknown";
                scale = 1.25;
              }
            ];
          }
          {
            profile.name = "haruka-docked";
            profile.outputs = [
              {
                criteria = "AU Optronics 0xD291 Unknown";
                scale = 1.25;
                position = "500,1440";
              }
              {
                criteria = "Samsung Electric Company LC32G5xT HNMN700045";
                scale = 1.00;
                position = "0,0";
              }
            ];
          }
        ];
      };

      mako = {
        enable = true;
      } // import ./config/mako.nix { inherit config neotheme; };

      swayidle =
        let
          # TODO: remove when >1.6.11
          # Fixes frequent RSOD
          swaylock-effects = pkgs.swaylock-effects.overrideAttrs {
            src = pkgs.fetchFromGitHub {
              owner = "jirutka";
              repo = "swaylock-effects";
              rev = "7c5681ce96587ce3090c6698501faeccdfdc157d";
              sha256 = "sha256-09Kq90wIIF9lPjiY2anf9MSgi/EqeXKXW1mFmhxA/aM=";
            };
          };
          lockCommand = ''${swaylock-effects}/bin/swaylock \
            --daemonize \
            --screenshots \
            --color ${neotheme.colors.background} \
            --clock \
            --indicator \
            --show-failed-attempts \
            --effect-blur 7x5 \
            --effect-vignette 0.5:0.5 \
            --fade-in 0.2'';
        in
        {
          enable = true;
          events = [
            {
              event = "before-sleep";
              command = "${pkgs.systemd}/bin/loginctl lock-session"
                + lib.optionalString (!cfg.laptop.enable) "; ${pkgs.openrgb}/bin/openrgb --mode static --color 000000";
            }
            { event = "lock"; command = lockCommand; }
          ] ++ lib.optionals (!cfg.laptop.enable) [{
            event = "after-resume";
            command = "${pkgs.openrgb}/bin/openrgb --mode static --color ffffff";
          }];
          timeouts = [
            # 4m30s
            { timeout = 270; command = "${pkgs.libnotify}/bin/notify-send -t 30000 'Locking screen in 30 seconds'"; }
            # 5m
            { timeout = 300; command = lockCommand; }
          ] ++ [
            {
              # 10m on laptops, 15m on desktop
              timeout = if cfg.laptop.enable then 600 else 900;
              command = "${pkgs.systemd}/bin/systemctl suspend";
            }
          ];
        };

      wlsunset = {
        enable = true;
        latitude = "36.5";
        longitude = "127.2";
      };
    };
  };
}