{
  config,
  lib,
  pkgs,
  ...
}:
let
  inherit (lib)
    concatStringsSep
    flip
    mapAttrsToList
    mkOption
    types
    ;

  cfg = config.programs.irssi;

  quoteStr = s: lib.escape [ ''"'' ] s;

  # Comma followed by newline.
  cnl = ''
    ,
  '';

  assignFormat =
    set: concatStringsSep "\n" (mapAttrsToList (k: v: "  ${k} = \"${quoteStr v}\";") set);

  chatnetString = concatStringsSep "\n" (
    flip mapAttrsToList cfg.networks (
      k: v: ''
        ${k} = {
          type = "${v.type}";
          nick = "${quoteStr v.nick}";
          autosendcmd = "${lib.concatMapStringsSep ";" quoteStr v.autoCommands}";
          ${lib.optionalString (v.saslExternal) ''
            sasl_username = "${quoteStr v.nick}";
              sasl_mechanism = "EXTERNAL";''}
        };
      ''
    )
  );

  serversString = concatStringsSep cnl (
    flip mapAttrsToList cfg.networks (
      k: v: ''
        {
          chatnet = "${k}";
          address = "${v.server.address}";
          port = "${toString v.server.port}";
          use_ssl = "${lib.hm.booleans.yesNo v.server.ssl.enable}";
          ssl_verify = "${lib.hm.booleans.yesNo v.server.ssl.verify}";
          autoconnect = "${lib.hm.booleans.yesNo v.server.autoConnect}";
          ${lib.optionalString (v.server.ssl.certificateFile != null) ''
            ssl_cert = "${v.server.ssl.certificateFile}";
          ''}
        }
      ''
    )
  );

  channelString = concatStringsSep cnl (
    lib.concatLists (
      flip mapAttrsToList cfg.networks (
        k: v:
        (flip mapAttrsToList v.channels (
          c: cv: ''
            {
              chatnet = "${k}";
              name = "${c}";
              autojoin = "${lib.hm.booleans.yesNo cv.autoJoin}";
            }
          ''
        ))
      )
    )
  );

  channelType = types.submodule {
    options = {
      name = mkOption {
        type = types.nullOr types.str;
        visible = false;
        default = null;
        description = "Name of the channel.";
      };

      autoJoin = mkOption {
        type = types.bool;
        default = false;
        description = "Whether to join this channel on connect.";
      };
    };
  };

  networkType = types.submodule (
    { name, ... }:
    {
      options = {
        name = mkOption {
          visible = false;
          default = name;
          type = types.str;
        };

        nick = mkOption {
          type = types.str;
          description = "Nickname in that network.";
        };

        type = mkOption {
          type = types.str;
          description = "Type of the network.";
          default = "IRC";
        };

        autoCommands = mkOption {
          type = types.listOf types.str;
          default = [ ];
          description = "List of commands to execute on connect.";
        };

        server = {
          address = mkOption {
            type = types.str;
            description = "Address of the chat server.";
          };

          port = mkOption {
            type = types.port;
            default = 6667;
            description = "Port of the chat server.";
          };

          ssl = {
            enable = mkOption {
              type = types.bool;
              default = true;
              description = "Whether SSL should be used.";
            };

            verify = mkOption {
              type = types.bool;
              default = true;
              description = "Whether the SSL certificate should be verified.";
            };

            certificateFile = mkOption {
              type = types.nullOr types.path;
              default = null;
              description = ''
                Path to a file containing the certificate used for
                client authentication to the server.
              '';
            };
          };

          autoConnect = mkOption {
            type = types.bool;
            default = false;
            description = "Whether Irssi connects to the server on launch.";
          };
        };

        channels = mkOption {
          description = "Channels for the given network.";
          type = types.attrsOf channelType;
          default = { };
        };

        saslExternal = mkOption {
          type = types.bool;
          default = false;
          description = ''
            Enable SASL external authentication. This requires setting a path in
            [](#opt-programs.irssi.networks._name_.server.ssl.certificateFile).
          '';
        };
      };
    }
  );

in
{

  options = {
    programs.irssi = {
      enable = lib.mkEnableOption "the Irssi chat client";

      package = lib.mkPackageOption pkgs "irssi" { nullable = true; };

      extraConfig = mkOption {
        default = "";
        description = "These lines are appended to the Irssi configuration.";
        type = types.lines;
      };

      aliases = mkOption {
        default = { };
        example = {
          J = "join";
          BYE = "quit";
        };
        description = "An attribute set that maps aliases to commands.";
        type = types.attrsOf types.str;
      };

      networks = mkOption {
        default = { };
        example = {
          liberachat = {
            nick = "hmuser";
            server = {
              address = "irc.libera.chat";
              port = 6697;
              autoConnect = true;
            };
            channels = {
              nixos.autoJoin = true;
            };
          };
        };
        description = "An attribute set of chat networks.";
        type = types.attrsOf networkType;
      };
    };
  };

  config = lib.mkIf cfg.enable {
    home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];

    home.file.".irssi/config".text = ''
      settings = {
        core = {
          settings_autosave = "no";
        };
      };

      aliases = {
      ${assignFormat cfg.aliases}
      };

      chatnets = {
      ${chatnetString}
      };

      servers = (
      ${serversString}
      );

      channels = (
      ${channelString}
      );

      ${cfg.extraConfig}
    '';
  };
}
