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

let
  cfg = config.services.librechat-oci;

  image = pkgs.dockerTools.pullImage {
    imageName = "ghcr.io/danny-avila/librechat";
    imageDigest = "sha256:a46254938507971e0d4f7ed3f9d116bd9b118f4810b5b75eb716baf575645068";
    hash = "sha256-zevUN6vrs3hymwCGFmk/YXlUzYjN37H+EO5aLxYchyc=";
    finalImageName = "ghcr.io/danny-avila/librechat";
    finalImageTag = "v0.8.5";
  };

  defaultEnv = {
    HOST = "0.0.0.0";
    PORT = "3080";
    NO_INDEX = "true";
    DEBUG_LOGGING = "false";
    CONSOLE_JSON = "false";
    ALLOW_REGISTRATION = "true";
    ALLOW_EMAIL_LOGIN = "true";
    SEARCH = "true";
    MEILI_NO_ANALYTICS = "true";
  };

  inherit (lib)
    literalExpression
    mkEnableOption
    mkIf
    mkOption
    mkOverride
    types
    ;
in
{
  options.services.librechat-oci = {
    enable = mkEnableOption "LibreChat container with Podman.";
    image = mkOption {
      type = types.package;
      default = image;
      description = "The Docker image to use (`pkgs.dockerTools.pullImage`).";
    };
    externalUrl = mkOption {
      type = types.nullOr types.str;
      default = null;
      example = literalExpression "http://${config.networking.domain}";
      description = "Public URL to configure for LibreChat.";
    };
    port = mkOption {
      type = types.port;
      default = 3080;
      description = "Which port the LibreChat server listens to.";
    };
    environment = mkOption {
      default = { };
      type = types.attrsOf types.str;
      description = ''
        Extra environment variables for LibreChat.
        For more details see <https://docs.librechat.ai/docs/configuration/dotenv>
      '';
    };
    environmentFile = mkOption {
      description = "Environment file to be passed to the LibreChat container.";
      type = types.nullOr types.path;
      default = null;
      example = "config.sops.templates.librechat-env.path";
    };
  };

  config = mkIf cfg.enable {
    virtualisation.podman = {
      enable = true;
      autoPrune.enable = true;
      dockerCompat = true;
    };

    networking.firewall.interfaces =
      let
        matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
      in
      {
        "${matchAll}".allowedUDPPorts = [ 53 ];
      };

    virtualisation.oci-containers.backend = "podman";

    virtualisation.oci-containers.containers."librechat-mongodb" = {
      image = "mongo:7.0";
      environment = {
        MONGO_INITDB_ROOT_USERNAME = "root";
        MONGO_INITDB_ROOT_PASSWORD = "librechat";
        MONGO_INITDB_DATABASE = "LibreChat";
      };
      volumes = [
        "librechat_mongodb_data:/data/db:rw"
      ];
      log-driver = "journald";
      extraOptions = [
        "--network=host"
      ];
    };

    virtualisation.oci-containers.containers.librechat = {
      image = toString cfg.image;
      environment =
        defaultEnv
        // {
          MONGO_URI = "mongodb://root:librechat@localhost:27017/LibreChat?authSource=admin";
        }
        // cfg.environment;
      volumes = [
        "librechat_data:/app/client/data:rw"
        "librechat_images:/app/client/public/images:rw"
        "librechat_uploads:/app/api/server/files/uploads:rw"
        "librechat_logs:/app/logs:rw"
      ];
      ports = [
        "${toString cfg.port}:${toString cfg.port}"
      ];
      log-driver = "journald";
      extraOptions = [
        "--network=host"
      ];
    };

    systemd.services."podman-librechat-mongodb" = {
      serviceConfig = {
        Restart = mkOverride 90 "always";
      };
      after = [
        "podman-volume-librechat_mongodb_data.service"
      ];
      requires = [
        "podman-volume-librechat_mongodb_data.service"
      ];
      partOf = [
        "podman-compose-librechat-root.target"
      ];
      wantedBy = [
        "podman-compose-librechat-root.target"
      ];
    };

    systemd.services."podman-librechat" = {
      serviceConfig = {
        Restart = mkOverride 90 "always";
      };
      after = [
        "podman-volume-librechat_data.service"
        "podman-volume-librechat_images.service"
        "podman-volume-librechat_uploads.service"
        "podman-volume-librechat_logs.service"
        "podman-librechat-mongodb.service"
      ];
      requires = [
        "podman-volume-librechat_data.service"
        "podman-volume-librechat_images.service"
        "podman-volume-librechat_uploads.service"
        "podman-volume-librechat_logs.service"
        "podman-librechat-mongodb.service"
      ];
      partOf = [
        "podman-compose-librechat-root.target"
      ];
      wantedBy = [
        "podman-compose-librechat-root.target"
      ];
    };

    systemd.services."podman-volume-librechat_data" = {
      path = [ pkgs.podman ];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = true;
      };
      script = ''
        podman volume inspect librechat_data || podman volume create librechat_data
      '';
      partOf = [ "podman-compose-librechat-root.target" ];
      wantedBy = [ "podman-compose-librechat-root.target" ];
    };

    systemd.services."podman-volume-librechat_images" = {
      path = [ pkgs.podman ];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = true;
      };
      script = ''
        podman volume inspect librechat_images || podman volume create librechat_images
      '';
      partOf = [ "podman-compose-librechat-root.target" ];
      wantedBy = [ "podman-compose-librechat-root.target" ];
    };

    systemd.services."podman-volume-librechat_uploads" = {
      path = [ pkgs.podman ];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = true;
      };
      script = ''
        podman volume inspect librechat_uploads || podman volume create librechat_uploads
      '';
      partOf = [ "podman-compose-librechat-root.target" ];
      wantedBy = [ "podman-compose-librechat-root.target" ];
    };

    systemd.services."podman-volume-librechat_logs" = {
      path = [ pkgs.podman ];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = true;
      };
      script = ''
        podman volume inspect librechat_logs || podman volume create librechat_logs
      '';
      partOf = [ "podman-compose-librechat-root.target" ];
      wantedBy = [ "podman-compose-librechat-root.target" ];
    };

    systemd.services."podman-volume-librechat_mongodb_data" = {
      path = [ pkgs.podman ];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = true;
      };
      script = ''
        podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data
      '';
      partOf = [ "podman-compose-librechat-root.target" ];
      wantedBy = [ "podman-compose-librechat-root.target" ];
    };

    systemd.targets."podman-compose-librechat-root" = {
      unitConfig = {
        Description = "Root target generated by compose2nix.";
      };
      wantedBy = [ "multi-user.target" ];
    };
  };
}
