{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  serviceInterface = import ../../lib/service-interface.nix {inherit lib;};

  cfg = config.homelab.services.influxdb;
  homelabCfg = config.homelab;

  # Service-specific options beyond the standard interface
  influxdbServiceOptions = {
    version = mkOption {
      type = types.enum ["1" "2"];
      default = "2";
      description = "InfluxDB version to use";
    };

    dataDir = mkOption {
      type = types.str;
      default = "/var/lib/influxdb";
      description = "Directory to store InfluxDB data";
    };

    # InfluxDB 2.x options
    v2 = {
      org = mkOption {
        type = types.str;
        default = "homelab";
        description = "Initial organization name";
      };

      bucket = mkOption {
        type = types.str;
        default = "homelab";
        description = "Initial bucket name";
      };

      username = mkOption {
        type = types.str;
        default = "admin";
        description = "Initial admin username";
      };

      password = mkOption {
        type = types.str;
        default = "changeme";
        description = "Initial admin password";
      };

      retention = mkOption {
        type = types.str;
        default = "30d";
        description = "Default retention period";
      };

      tokenFile = mkOption {
        type = types.nullOr types.path;
        default = null;
        description = "File containing the admin token";
      };
    };

    # InfluxDB 1.x options
    v1 = {
      database = mkOption {
        type = types.str;
        default = "homelab";
        description = "Default database name";
      };

      retention = mkOption {
        type = types.str;
        default = "30d";
        description = "Default retention period";
      };

      adminUser = mkOption {
        type = types.str;
        default = "admin";
        description = "Admin username";
      };

      adminPassword = mkOption {
        type = types.str;
        default = "changeme";
        description = "Admin password";
      };

      httpAuth = {
        enable = mkOption {
          type = types.bool;
          default = true;
          description = "Enable HTTP authentication";
        };
      };
    };

    extraConfig = mkOption {
      type = types.attrs;
      default = {};
      description = "Additional InfluxDB configuration";
    };

    backup = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = "Enable automatic backups";
      };

      schedule = mkOption {
        type = types.str;
        default = "daily";
        description = "Backup schedule";
      };

      retention = mkOption {
        type = types.str;
        default = "7d";
        description = "Backup retention period";
      };
    };
  };

  # Generate configuration based on version
  influxdbConfig =
    if cfg.version == "2"
    then
      recursiveUpdate {
        bolt-path = "${cfg.dataDir}/influxd.bolt";
        engine-path = "${cfg.dataDir}/engine";
        http-bind-address = "0.0.0.0:${toString cfg.port}";
        reporting-disabled = true;
        log-level = "info";
      }
      cfg.extraConfig
    else
      recursiveUpdate {
        meta = {
          dir = "${cfg.dataDir}/meta";
        };
        data = {
          dir = "${cfg.dataDir}/data";
          wal-dir = "${cfg.dataDir}/wal";
        };
        http = {
          bind-address = "0.0.0.0:${toString cfg.port}";
          auth-enabled = cfg.v1.httpAuth.enable;
        };
        logging = {
          level = "info";
        };
        reporting-disabled = true;
      }
      cfg.extraConfig;
in {
  options.homelab.services.influxdb = serviceInterface.mkServiceInterface {
    serviceName = "influxdb";
    defaultPort = 8086;
    defaultSubdomain = "influxdb";
    monitoringPath = "/metrics";
    healthCheckPath =
      if cfg.version == "2"
      then "/health"
      else "/ping";
    healthCheckConditions =
      if cfg.version == "2"
      then ["[STATUS] == 200" "[BODY].status == pass"]
      else ["[STATUS] == 204" "[RESPONSE_TIME] < 1000"];
    serviceOptions = influxdbServiceOptions;
  };

  config = serviceInterface.mkServiceConfig {
    inherit config cfg homelabCfg;
    serviceName = "influxdb";

    extraMonitoringLabels = {
      component = "timeseries-database";
      version = cfg.version;
    };

    customHealthChecks =
      [
        {
          name = "influxdb-query";
          port = cfg.port;
          path =
            if cfg.version == "2"
            then "/api/v2/query"
            else "/query";
          interval = "60s";
          method = "POST";
          conditions = [
            "[STATUS] < 500"
            "[RESPONSE_TIME] < 3000"
          ];
          group = "monitoring";
          labels = {
            service = "influxdb";
            component = "query-engine";
          };
        }
      ]
      ++ optional (cfg.version == "2") {
        name = "influxdb-write";
        port = cfg.port;
        path = "/api/v2/write";
        interval = "60s";
        method = "POST";
        conditions = [
          "[STATUS] < 500"
          "[RESPONSE_TIME] < 2000"
        ];
        group = "monitoring";
        labels = {
          service = "influxdb";
          component = "write-engine";
        };
      };

    serviceConfig = mkMerge [
      # Common configuration
      {
        # Create data directories
        systemd.tmpfiles.rules =
          [
            "d ${cfg.dataDir} 0755 influxdb influxdb -"
          ]
          ++ optionals (cfg.version == "1") [
            "d ${cfg.dataDir}/meta 0755 influxdb influxdb -"
            "d ${cfg.dataDir}/data 0755 influxdb influxdb -"
            "d ${cfg.dataDir}/wal 0755 influxdb influxdb -"
          ];

        # Ensure influxdb user exists
        users.users.influxdb = {
          isSystemUser = true;
          group = "influxdb";
          home = cfg.dataDir;
          createHome = true;
        };

        users.groups.influxdb = {};
      }

      # InfluxDB 2.x configuration
      (mkIf (cfg.version == "2") {
        services.influxdb2 = {
          enable = true;
          dataDir = cfg.dataDir;
          settings = influxdbConfig;
        };

        # Initial setup for InfluxDB 2.x
        systemd.services.influxdb2-setup = {
          description = "InfluxDB 2.x initial setup";
          after = ["influxdb2.service"];
          wants = ["influxdb2.service"];
          wantedBy = ["multi-user.target"];
          serviceConfig = {
            Type = "oneshot";
            RemainAfterExit = true;
            User = "influxdb";
            Group = "influxdb";
          };
          script = let
            setupScript = pkgs.writeShellScript "influxdb2-setup" ''
              # Wait for InfluxDB to be ready
              timeout=60
              while [ $timeout -gt 0 ]; do
                if ${pkgs.curl}/bin/curl -f http://localhost:${toString cfg.port}/health > /dev/null 2>&1; then
                  break
                fi
                sleep 1
                timeout=$((timeout - 1))
              done

              # Check if setup is already done
              if ${pkgs.curl}/bin/curl -f http://localhost:${toString cfg.port}/api/v2/setup > /dev/null 2>&1; then
                # Setup InfluxDB if not already done
                ${pkgs.influxdb2}/bin/influx setup \
                  --host http://localhost:${toString cfg.port} \
                  --org "${cfg.v2.org}" \
                  --bucket "${cfg.v2.bucket}" \
                  --username "${cfg.v2.username}" \
                  --password "${cfg.v2.password}" \
                  --retention "${cfg.v2.retention}" \
                  --force
              fi
            '';
          in "${setupScript}";
        };
      })

      # InfluxDB 1.x configuration
      (mkIf (cfg.version == "1") {
        services.influxdb = {
          enable = true;
          dataDir = cfg.dataDir;
          extraConfig = influxdbConfig;
        };

        # Initial setup for InfluxDB 1.x
        systemd.services.influxdb-setup = mkIf cfg.v1.httpAuth.enable {
          description = "InfluxDB 1.x initial setup";
          after = ["influxdb.service"];
          wants = ["influxdb.service"];
          wantedBy = ["multi-user.target"];
          serviceConfig = {
            Type = "oneshot";
            RemainAfterExit = true;
            User = "influxdb";
            Group = "influxdb";
          };
          script = let
            setupScript = pkgs.writeShellScript "influxdb-setup" ''
              # Wait for InfluxDB to be ready
              timeout=60
              while [ $timeout -gt 0 ]; do
                if ${pkgs.curl}/bin/curl -f http://localhost:${toString cfg.port}/ping > /dev/null 2>&1; then
                  break
                fi
                sleep 1
                timeout=$((timeout - 1))
              done

              # Create admin user
              ${pkgs.influxdb}/bin/influx -host localhost -port ${toString cfg.port} -execute "CREATE USER \"${cfg.v1.adminUser}\" WITH PASSWORD '${cfg.v1.adminPassword}' WITH ALL PRIVILEGES" || true

              # Create database
              ${pkgs.influxdb}/bin/influx -host localhost -port ${toString cfg.port} -username "${cfg.v1.adminUser}" -password "${cfg.v1.adminPassword}" -execute "CREATE DATABASE \"${cfg.v1.database}\"" || true

              # Set retention policy
              ${pkgs.influxdb}/bin/influx -host localhost -port ${toString cfg.port} -username "${cfg.v1.adminUser}" -password "${cfg.v1.adminPassword}" -database "${cfg.v1.database}" -execute "CREATE RETENTION POLICY \"default\" ON \"${cfg.v1.database}\" DURATION ${cfg.v1.retention} REPLICATION 1 DEFAULT" || true
            '';
          in "${setupScript}";
        };
      })

      # Backup configuration
      (mkIf cfg.backup.enable {
        systemd.services.influxdb-backup = {
          description = "InfluxDB backup";
          serviceConfig = {
            Type = "oneshot";
            User = "influxdb";
            Group = "influxdb";
          };
          script = let
            backupScript =
              if cfg.version == "2"
              then
                pkgs.writeShellScript "influxdb2-backup" ''
                  backup_dir="${cfg.dataDir}/backups/$(date +%Y%m%d_%H%M%S)"
                  mkdir -p "$backup_dir"
                  ${pkgs.influxdb2}/bin/influx backup \
                    --host http://localhost:${toString cfg.port} \
                    --org "${cfg.v2.org}" \
                    "$backup_dir"

                  # Clean old backups
                  find "${cfg.dataDir}/backups" -type d -mtime +${cfg.backup.retention} -exec rm -rf {} + || true
                ''
              else
                pkgs.writeShellScript "influxdb-backup" ''
                  backup_dir="${cfg.dataDir}/backups/$(date +%Y%m%d_%H%M%S)"
                  mkdir -p "$backup_dir"
                  ${pkgs.influxdb}/bin/influxd backup \
                    -host localhost:${toString cfg.port} \
                    -database "${cfg.v1.database}" \
                    "$backup_dir"

                  # Clean old backups
                  find "${cfg.dataDir}/backups" -type d -mtime +${cfg.backup.retention} -exec rm -rf {} + || true
                '';
          in "${backupScript}";
        };

        systemd.timers.influxdb-backup = {
          description = "InfluxDB backup timer";
          wantedBy = ["timers.target"];
          timerConfig = {
            OnCalendar = cfg.backup.schedule;
            Persistent = true;
            RandomizedDelaySec = "5m";
          };
        };

        # Create backup directory
        systemd.tmpfiles.rules = [
          "d ${cfg.dataDir}/backups 0755 influxdb influxdb -"
        ];
      })
    ];
  };
}
