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

let
  inherit (lib) mkEnableOption mkIf readFile;
in
{
  home-manager.users.moritz.programs.nixvim = {
    plugins.conform-nvim = {
      enable = true;
      settings.formatters_by_ft = {
        "*" = [ "codespell" "trim_whitespace" ];
        elixir = [ "mix" ];
        gleam = [ "gleam" ];
        go = [ "gofmt" ];
        json = [ "jq" ];
        lua = [ "stylua" ];
        nix = [ "nixpkgs_fmt" ];
        python.__raw = ''
          function(bufnr)
            return { first(bufnr, "ruff_organize_imports", "isort"), first(bufnr, "ruff_format", "black")}
          end
        '';
        rust = [ "rustfmt" ];
        sh = [ "shfmt" ];
        tex = [ "latexindent" ];
        toml = [ "taplo" ];
        yaml = [ "yamlfix" ];
        markdown = [ "injected" ];
      };
    };
    opts.formatexpr = "v:lua.require'conform'.formatexpr()";
    extraConfigLuaPre = ''
      ---@param bufnr integer
      ---@param ... string
      ---@return string
      local function first(bufnr, ...)
        local conform = require("conform")
        for i = 1, select("#", ...) do
          local formatter = select(i, ...)
          if conform.get_formatter_info(formatter, bufnr).available then
            return formatter
          end
        end
        return select(1, ...)
      end

      vim.api.nvim_create_user_command("Format", function(opts)
        require("conform").format({ formatters = opts.fargs })
      end, {
        nargs = "+",
        complete = function()
          local formatters_by_ft = require("conform").formatters_by_ft
          local names = formatters_by_ft[vim.bo.filetype] or formatters_by_ft["_"] or {}
          names = vim.list_extend(names, formatters_by_ft["*"] or {})
          names = vim.tbl_flatten(names)
          local formatters = vim.tbl_map(require("conform").get_formatter_info, names)
          formatters = vim.tbl_filter(function(formatter)
            return formatter.available
          end, formatters)
          return vim.tbl_map(function(formatter_info)
            return formatter_info.name
          end, formatters)
        end,
      })
    '';
    performance.combinePlugins.standalonePlugins = [
      "conform.nvim"
    ];
    keymaps = [
      { key = "="; action.__raw = ''function() require("conform").format() end''; options.desc = "Format current file"; }
    ];
  };

}
