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

with lib;

let
  cfg = config.settings.applications.helix;
in {
  options = {
    settings.applications.helix.enable = lib.mkOption {
      type = lib.types.bool;
      description = ''
        Enable helix text editor
      '';
    };

    settings.applications.helix.markdown = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable markdown language support
      '';
    };

    settings.applications.helix.systemverilog = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable systemverilog language support
      '';
    };

    settings.applications.helix.nix = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = ''
        Enable nix language support
      '';
    };

    settings.applications.helix.latex = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = ''
        Enable latex language support
      '';
    };

    settings.applications.helix.vue = lib.mkOption {
      type = lib.types.bool;
      default = true;
      description = ''
        Enable vue/nuxt language support
      '';
    };

    settings.applications.helix.rust = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable rust language support
      '';
    };
  };

  config = mkIf cfg.enable {
    home.packages = with pkgs; lib.concatLists [
      (lib.optionals cfg.markdown [ unstable.marksman unstable.markdown-oxide dprint ])
      (lib.optionals cfg.systemverilog [ unstable.svls ])
      (lib.optionals cfg.nix [ unstable.nix unstable.nixpkgs-fmt ])
      (lib.optionals cfg.latex [ tectonic unstable.texlab ])
      (lib.optionals cfg.vue [ unstable.vue-language-server unstable.typescript unstable.typescript-language-server ])
    ];

    # Markdown
    home.file.".config/.dprint.json" = lib.mkIf cfg.markdown {
      text = ''
        {
          "markdown": {
            "lineWidth":120,
          },
          "excludes": [],
          "plugins": [
            "https://plugins.dprint.dev/markdown-0.16.1.wasm"
          ]
        }
      '';
    };

    programs.helix = {
      enable = true;
      package = pkgs.unstable.helix;
      defaultEditor = true;
      settings = {
        editor.cursor-shape = {
          insert = "bar";
        };
        editor.end-of-line-diagnostics = "hint";
        editor.inline-diagnostics.cursor-line = "error";
      };
      languages = {
        # Rust
        language-server.rust-analyzer.config = lib.mkIf cfg.rust {
          cargo = {
            features = "all";
          };
        };

        # Systemverilog
        language-server.svls = lib.mkIf cfg.systemverilog {
          command = "svls";
        };

        # Latex
        language-server.texlab = lib.mkIf cfg.latex {
          config = {
            texlab.chktex = {
              onOpenAndSave = true;
              onEdit = true;
            };
            texlab.forwardSearch = {
              executable = "zathura";
              args = [
                "--synctex-forward"
                "%l:%c:%f"
                "%p"
              ];
            };
            texlab.build = {
              auxDirectory = "build";
              logDirectory = "build";
              pdfDirectory = "build";
              forwardSearchAfter = true;
              onSave = true;
              executable = "tectonic";
              args = [
                "-X"
                "compile"
                "--synctex"
                "--keep-logs"
                "--keep-intermediates"
                "--outdir=build"
                "%f"
              ];
            };
          };
        };

        language-server.typescript-language-server.config = lib.mkIf cfg.vue {
          # tsserver = {
          #   path = "${pkgs.unstable.typescript}/bin/tsserver";
          # };
          plugins = [
            {
              name = "@vue/typescript-plugin";
              location = "${pkgs.unstable.vue-language-server}/bin/vue-language-server}";
              languages = ["vue"];
            }
          ];

          vue.inlayHints = {
            includeInlayEnumMemberValueHints = true;
            includeInlayFunctionLikeReturnTypeHints = true;
            includeInlayFunctionParameterTypeHints = true;
            includeInlayParameterNameHints = "all";
            includeInlayParameterNameHintsWhenArgumentMatchesName = true;
            includeInlayPropertyDeclarationTypeHints = true;
            includeInlayVariableTypeHints = true;
          };
        };
          # language-server.vue-language-server = {
          #   command = "${pkgs.vue-language-server}/bin/vue-language-server";
          #   args = [ "--stdio" ];
          #   config = {
          #     typescript = {
          #       tsdk = "${pkgs.typescript}/bin/";
          #     };
          #   };
          # };

        language = lib.concatLists [
          (lib.optionals cfg.systemverilog [{
            name = "verilog";
            language-servers = [ "svls" ];
          }])
          (lib.optionals cfg.markdown [{
            name = "markdown";
            auto-format = true;
            language-servers = [ "markdown-oxide" ];
            formatter.command = "dprint";
            formatter.args = ["fmt" "--stdin" "md" "--config" "/home/xeovalyte/.config/.dprint.json"];
          }
          {
            name = "typst";
            auto-format = false;
            formatter.command = "${pkgs.typstfmt}/bin/typstfmt";
          }])
          (lib.optionals cfg.vue [{
            name = "vue";
            language-servers = ["vuels" "typescript-language-server"];
          }])
        ];
      };
    };
  };
}
