{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.homelab.services.grafana;
  homelabCfg = config.homelab;

  # Default dashboards for homelab monitoring
  defaultDashboards = {
    "node-exporter" = pkgs.fetchurl {
      url = "https://grafana.com/api/dashboards/1860/revisions/37/download";
      sha256 = "sha256-0000000000000000000000000000000000000000000="; # You'll need to update this
    };
    "prometheus-stats" = pkgs.fetchurl {
      url = "https://grafana.com/api/dashboards/2/revisions/2/download";
      sha256 = "sha256-0000000000000000000000000000000000000000000="; # You'll need to update this
    };
  };

  # Grafana provisioning configuration
  provisioningConfig = {
    # Data sources
    datasources =
      [
        {
          name = "Prometheus";
          type = "prometheus";
          access = "proxy";
          url = cfg.datasources.prometheus.url;
          isDefault = true;
          editable = false;
          jsonData = {
            timeInterval = "5s";
            queryTimeout = "60s";
            httpMethod = "POST";
          };
        }
      ]
      ++ cfg.datasources.extra;

    # Dashboard providers
    dashboards = [
      {
        name = "homelab";
        type = "file";
        disableDeletion = false;
        updateIntervalSeconds = 10;
        allowUiUpdates = true;
        options = {
          path = "/var/lib/grafana/dashboards";
        };
      }
    ];

    # Notification channels
    notifiers = cfg.notifications;
  };
in {
  options.homelab.services.grafana = {
    enable = mkEnableOption "Grafana dashboard service";

    port = mkOption {
      type = types.port;
      default = 3000;
      description = "Port for Grafana web interface";
    };

    openFirewall = mkOption {
      type = types.bool;
      default = true;
      description = "Whether to open firewall ports";
    };

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

    domain = mkOption {
      type = types.str;
      default = "grafana.${homelabCfg.externalDomain}";
      description = "Domain for Grafana";
    };

    rootUrl = mkOption {
      type = types.str;
      default = "https://grafana.${homelabCfg.externalDomain}";
      description = "Root URL for Grafana";
    };

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

      password = mkOption {
        type = types.str;
        default = "admin";
        description = "Admin password (change this!)";
      };

      email = mkOption {
        type = types.str;
        default = "admin@${homelabCfg.externalDomain}";
        description = "Admin email";
      };
    };

    datasources = {
      prometheus = {
        url = mkOption {
          type = types.str;
          default = "http://localhost:9090";
          description = "Prometheus URL";
        };
      };

      extra = mkOption {
        type = types.listOf types.attrs;
        default = [];
        description = "Additional data sources";
        example = literalExpression ''
          [
            {
              name = "Loki";
              type = "loki";
              url = "http://localhost:3100";
            }
          ]
        '';
      };
    };

    notifications = mkOption {
      type = types.listOf types.attrs;
      default = [];
      description = "Notification channels configuration";
      example = literalExpression ''
        [
          {
            name = "discord-webhook";
            type = "discord";
            settings = {
              url = "https://discord.com/api/webhooks/...";
              username = "Grafana";
            };
          }
        ]
      '';
    };

    plugins = mkOption {
      type = types.listOf types.str;
      default = [
        "grafana-piechart-panel"
        "grafana-worldmap-panel"
        "grafana-clock-panel"
        "grafana-simple-json-datasource"
      ];
      description = "Grafana plugins to install";
    };

    smtp = {
      enabled = mkOption {
        type = types.bool;
        default = false;
        description = "Enable SMTP for email notifications";
      };

      host = mkOption {
        type = types.str;
        default = "localhost:587";
        description = "SMTP server host:port";
      };

      user = mkOption {
        type = types.str;
        default = "";
        description = "SMTP username";
      };

      password = mkOption {
        type = types.str;
        default = "";
        description = "SMTP password";
      };

      fromAddress = mkOption {
        type = types.str;
        default = "grafana@${homelabCfg.externalDomain}";
        description = "From email address";
      };

      fromName = mkOption {
        type = types.str;
        default = "Homelab Grafana";
        description = "From name";
      };
    };

    security = {
      allowEmbedding = mkOption {
        type = types.bool;
        default = false;
        description = "Allow embedding Grafana in iframes";
      };

      cookieSecure = mkOption {
        type = types.bool;
        default = true;
        description = "Set secure flag on cookies";
      };

      secretKey = mkOption {
        type = types.str;
        default = "change-this-secret-key";
        description = "Secret key for signing (change this!)";
      };
    };

    auth = {
      anonymousEnabled = mkOption {
        type = types.bool;
        default = false;
        description = "Enable anonymous access";
      };

      disableLoginForm = mkOption {
        type = types.bool;
        default = false;
        description = "Disable login form";
      };
    };

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

  config = mkIf cfg.enable {
    services.grafana = {
      enable = true;
      settings =
        recursiveUpdate {
          server = {
            http_addr = "0.0.0.0";
            http_port = cfg.port;
            domain = cfg.domain;
            root_url = cfg.rootUrl;
            serve_from_sub_path = false;
          };

          database = {
            type = "sqlite3";
            path = "${cfg.dataDir}/grafana.db";
          };

          security = {
            admin_user = cfg.admin.user;
            admin_password = cfg.admin.password;
            admin_email = cfg.admin.email;
            allow_embedding = cfg.security.allowEmbedding;
            cookie_secure = cfg.security.cookieSecure;
            secret_key = cfg.security.secretKey;
          };

          users = {
            allow_sign_up = false;
            auto_assign_org = true;
            auto_assign_org_role = "Viewer";
          };

          auth.anonymous = {
            enabled = cfg.auth.anonymousEnabled;
            org_name = "Homelab";
            org_role = "Viewer";
          };

          auth.basic = {
            enabled = !cfg.auth.disableLoginForm;
          };

          smtp = mkIf cfg.smtp.enabled {
            enabled = true;
            host = cfg.smtp.host;
            user = cfg.smtp.user;
            password = cfg.smtp.password;
            from_address = cfg.smtp.fromAddress;
            from_name = cfg.smtp.fromName;
          };

          analytics = {
            reporting_enabled = false;
            check_for_updates = false;
          };

          log = {
            mode = "console";
            level = "info";
          };

          paths = {
            data = cfg.dataDir;
            logs = "${cfg.dataDir}/log";
            plugins = "${cfg.dataDir}/plugins";
            provisioning = "/etc/grafana/provisioning";
          };
        }
        cfg.extraConfig;

      dataDir = cfg.dataDir;
    };

    # Install plugins
    systemd.services.grafana.preStart = mkIf (cfg.plugins != []) (
      concatStringsSep "\n" (map (
          plugin: "${pkgs.grafana}/bin/grafana-cli --pluginsDir ${cfg.dataDir}/plugins plugins install ${plugin} || true"
        )
        cfg.plugins)
    );

    # Provisioning configuration
    environment.etc =
      {
        "grafana/provisioning/datasources/datasources.yaml".text = builtins.toJSON {
          apiVersion = 1;
          datasources = provisioningConfig.datasources;
        };

        "grafana/provisioning/dashboards/dashboards.yaml".text = builtins.toJSON {
          apiVersion = 1;
          providers = provisioningConfig.dashboards;
        };
      }
      // (mkIf (cfg.notifications != []) {
        "grafana/provisioning/notifiers/notifiers.yaml".text = builtins.toJSON {
          apiVersion = 1;
          notifiers = provisioningConfig.notifiers;
        };
      });

    # Create dashboard directory
    systemd.tmpfiles.rules = [
      "d ${cfg.dataDir}/dashboards 0755 grafana grafana -"
    ];

    # Open firewall if requested
    networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [cfg.port];

    # Add to monitoring endpoints
    homelab.monitoring.metrics = [
      {
        name = "grafana";
        port = cfg.port;
        path = "/metrics";
        jobName = "grafana";
        labels = {
          service = "grafana";
          component = "monitoring";
        };
      }
    ];

    # Add health checks
    homelab.monitoring.healthChecks = [
      {
        name = "grafana-web-interface";
        port = cfg.port;
        path = "/api/health";
        interval = "30s";
        conditions = [
          "[STATUS] == 200"
          "[BODY].database == ok"
          "[RESPONSE_TIME] < 2000"
        ];
        group = "monitoring";
        labels = {
          service = "grafana";
          component = "web-interface";
        };
      }
      {
        name = "grafana-login-page";
        port = cfg.port;
        path = "/login";
        interval = "60s";
        conditions = [
          "[STATUS] == 200"
          "[RESPONSE_TIME] < 3000"
        ];
        group = "monitoring";
        labels = {
          service = "grafana";
          component = "login";
        };
      }
    ];

    # Add reverse proxy entry
    homelab.reverseProxy.entries = [
      {
        subdomain = "grafana";
        host = homelabCfg.hostname;
        port = cfg.port;
      }
    ];
  };
}
