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

  extractServiceData = services:
    mapAttrsToList (name: svc: {
      inherit name;
      enabled = svc.enable or false;
      port = svc.port or null;
      description = svc.description or name;
      tags = svc.tags or [];
      systemdServices = svc.systemdServices or ["${name}.service" name];
    }) (filterAttrs (name: svc: svc.enable or false) services);

  extractListData = list:
    if isList list
    then
      map (
        item:
          if isAttrs item
          then
            filterAttrs (
              k: v:
                !(isFunction v)
                && !(isAttrs v && v ? "_type")
                && k != "_module"
            )
            item
          else item
      )
      list
    else [];

  homelabCli = pkgs.writeShellScriptBin "homelab" ''
    #!/usr/bin/env bash
    set -euo pipefail

    HOMELAB_CONFIG="/etc/homelab/config.json"

    # Colors
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    NC='\033[0m'

    # Helper functions
    error() { echo -e "''${RED}Error: $1''${NC}" >&2; }
    info() { echo -e "''${BLUE}$1''${NC}"; }
    success() { echo -e "''${GREEN}$1''${NC}"; }
    warn() { echo -e "''${YELLOW}$1''${NC}"; }

    # Check config exists
    if [[ ! -f "$HOMELAB_CONFIG" ]]; then
        error "Homelab configuration not found"
        error "Make sure homelab.enable = true and rebuild"
        exit 1
    fi

    # Load command implementations
    source ${./cli-commands.sh}

    # Help function
    show_help() {
        cat << 'EOF'
    Homelab Management CLI

    USAGE:
        homelab <command> [options]

    COMMANDS:
        services    List and manage services
        backups     Show backup jobs and status
        proxy       Show reverse proxy entries
        monitoring  Show monitoring configuration
        status      Overall homelab status
        help        Show this help

    GLOBAL OPTIONS:
        --global, -g    Show fleet-wide information
        --local, -l     Show local information (default)
        --json          Output JSON format
        --help, -h      Show help

    EXAMPLES:
        homelab services --global
        homelab backups --local
        homelab status
    EOF
    }

    # Main command dispatcher
    case "''${1:-help}" in
        services)
            shift
            cmd_services "$@"
            ;;
        backups)
            shift
            cmd_backups "$@"
            ;;
        proxy)
            shift
            cmd_proxy "$@"
            ;;
        monitoring)
            shift
            cmd_monitoring "$@"
            ;;
        status)
            shift
            cmd_status "$@"
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            error "Unknown command: $1"
            show_help
            exit 1
            ;;
    esac
  '';
in {
  # Only enable when homelab is enabled
  config = mkIf cfg.enable {
    # Install CLI tools
    environment.systemPackages = [
      homelabCli
      # Create convenient aliases
      (pkgs.writeShellScriptBin "hl" "exec homelab \"$@\"")
      (pkgs.writeShellScriptBin "hls" "exec homelab services \"$@\"")
      (pkgs.writeShellScriptBin "hlb" "exec homelab backups \"$@\"")
      (pkgs.writeShellScriptBin "hlp" "exec homelab proxy \"$@\"")
      (pkgs.writeShellScriptBin "hlm" "exec homelab monitoring \"$@\"")
    ];

    # Generate minimal, safe JSON config
    environment.etc."homelab/config.json" = {
      text = builtins.toJSON {
        # Basic homelab info (always safe)
        hostname = cfg.hostname or "unknown";
        domain = cfg.domain or "lab";
        externalDomain = cfg.externalDomain or "lab.local";
        environment = cfg.environment or "production";
        location = cfg.location or "homelab";
        tags = cfg.tags or [];

        # Services - only extract what we have locally
        services = {
          local = {
            all =
              if (cfg ? services)
              then extractServiceData cfg.services
              else [];
            count =
              if (cfg ? services)
              then length (attrNames (filterAttrs (n: s: s.enable or false) cfg.services))
              else 0;
          };
          # For global data, we'll try to read it but provide empty fallback
          global = {
            all = [];
            count = 0;
            summary = {};
          };
        };

        # Monitoring - extract only basic data
        monitoring = {
          local = {
            allMetrics =
              if (hasAttr "monitoring" cfg && hasAttr "allMetrics" cfg.monitoring)
              then extractListData cfg.monitoring.allMetrics
              else [];
            allHealthChecks =
              if (hasAttr "monitoring" cfg && hasAttr "allHealthChecks" cfg.monitoring)
              then extractListData cfg.monitoring.allHealthChecks
              else [];
            count =
              if (hasAttr "monitoring" cfg && hasAttr "allMetrics" cfg.monitoring)
              then length cfg.monitoring.allMetrics
              else 0;
          };
          global = {
            allMetrics = [];
            allHealthChecks = [];
            summary = {
              totalMetrics = 0;
              totalHealthChecks = 0;
            };
          };
        };

        # Logging
        logging = {
          local = {
            allSources =
              if (hasAttr "logging" cfg && hasAttr "allSources" cfg.logging)
              then extractListData cfg.logging.allSources
              else [];
            count =
              if (hasAttr "logging" cfg && hasAttr "allSources" cfg.logging)
              then length cfg.logging.allSources
              else 0;
          };
          global = {
            allSources = [];
            summary = {};
          };
        };

        # Backups
        backups = {
          local = {
            allJobs =
              if (hasAttr "backups" cfg && hasAttr "allJobs" cfg.backups)
              then extractListData cfg.backups.allJobs
              else [];
            count =
              if (hasAttr "backups" cfg && hasAttr "allJobs" cfg.backups)
              then length cfg.backups.allJobs
              else 0;
          };
          global = {
            allJobs = [];
            summary = {};
          };
        };

        # Reverse Proxy
        reverseProxy = {
          local = {
            allEntries =
              if (hasAttr "reverseProxy" cfg && hasAttr "allEntries" cfg.reverseProxy)
              then extractListData cfg.reverseProxy.allEntries
              else [];
            count =
              if (hasAttr "reverseProxy" cfg && hasAttr "allEntries" cfg.reverseProxy)
              then length cfg.reverseProxy.allEntries
              else 0;
          };
          global = {
            allEntries = [];
            summary = {};
          };
        };

        # Metadata
        _metadata = {
          # generated = toString builtins.currentTime;
          version = "1.0.0";
        };
      };
      mode = "0644";
    };

    # Add bash completion
    environment.etc."bash_completion.d/homelab".text = ''
      _homelab_completion() {
        local cur prev opts
        COMPREPLY=()
        cur="''${COMP_WORDS[COMP_CWORD]}"
        prev="''${COMP_WORDS[COMP_CWORD-1]}"

        case ''${COMP_CWORD} in
          1)
            opts="services backups proxy monitoring status help"
            COMPREPLY=( $(compgen -W "''${opts}" -- ''${cur}) )
            return 0
            ;;
          *)
            case ''${COMP_WORDS[1]} in
              services|backups|proxy|monitoring|status)
                opts="--global --local --json --help"
                ;;
              *)
                opts="--help"
                ;;
            esac
            COMPREPLY=( $(compgen -W "''${opts}" -- ''${cur}) )
            return 0
            ;;
        esac
      }

      complete -F _homelab_completion homelab hl
    '';
  };
}
