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

let
  nodejs = pkgs.nodejs_22;

  npmDeps = pkgs.importNpmLock.buildNodeModules {
    npmRoot = ./.;
    inherit nodejs;
  };

  ensureNodeDeps = ''
    if [ -e "$DEVENV_ROOT/node_modules" ] && [ ! -L "$DEVENV_ROOT/node_modules" ]; then
      rm -rf "$DEVENV_ROOT/node_modules"
    fi
    ln -sfn "$CULTGUARD_NPM_DEPS/node_modules" "$DEVENV_ROOT/node_modules"
    export PATH="$DEVENV_ROOT/node_modules/.bin:$PATH"
  '';

  runTs = entry: ''
    ${ensureNodeDeps}
    cd "$DEVENV_ROOT"
    exec tsx "${entry}" "$@"
  '';

  # Metabase wrapper script - H2 database stored in .devenv/state for persistence
  metabaseStart = pkgs.writeShellScriptBin "metabase-start" ''
    export MB_DB_TYPE=h2
    export MB_DB_FILE="$DEVENV_ROOT/.devenv/state/metabase/metabase"
    export MB_JETTY_PORT=3100
    export MB_JETTY_HOST=0.0.0.0
    export MB_PLUGINS_DIR="$DEVENV_ROOT/.devenv/state/metabase/plugins"
    export MB_SEND_EMAIL_ON_FIRST_LOGIN=false
    mkdir -p "$DEVENV_ROOT/.devenv/state/metabase"
    exec ${pkgs.metabase}/bin/metabase
  '';

  privacy = import ./nix/privacy-stack.nix {
    inherit pkgs lib config;
  };
in {

  # ─── PACKAGES ──────────────────────────────────────────────────────────────
  packages = with pkgs; [
    metabaseStart
    postgresql_16                      # psql CLI, pg_dump, etc.
    nodejs                            # Node.js runtime pinned by Nix
    curl
    jq
    sqlite                             # keep for reading legacy osint.db
    iproute2
    openbox
    socat
    sops
    ssh-to-age
    wireguard-tools
    microsocks
    x11vnc
    xorg.xorgserver
    xorg.xdpyinfo
    yq-go
    privacy.piPkg
    privacy.gotatun
    pkgs.wireproxy
    privacy.privacyChromium            # browser for FB scraper and privacy runtime
  ];

  # ─── LANGUAGES ─────────────────────────────────────────────────────────────
  # Node.js for all TypeScript tooling.
  # Dependencies are pinned in package-lock.json and linked from the Nix store.
  languages.javascript = {
    enable = true;
    package = nodejs;
  };

  # ─── SERVICES ──────────────────────────────────────────────────────────────
  services.postgres = {
    enable  = true;
    package = pkgs.postgresql_16;

    extensions = extensions: [
      extensions.pgvector   # vector similarity search
    ];

    settings = {
      # Unix socket only — no TCP, no port conflicts.
      # Socket lives inside the project so nothing leaks to /run/user/...
      listen_addresses      = lib.mkForce "";
      port                  = lib.mkForce 5433;
      unix_socket_directories = lib.mkForce "${config.devenv.state}/postgres";

      # Tuning for analytical / embedding workloads
      shared_buffers       = "256MB";
      work_mem             = "64MB";
      maintenance_work_mem = "128MB";
      effective_cache_size = "1GB";
      wal_level            = "minimal";
      max_wal_senders      = 0;
    };

    initialDatabases = [
      { name = "cultguard"; }   # OSINT data
    ];

    # Install extensions on first init
    initialScript = ''
      \c cultguard
      CREATE EXTENSION IF NOT EXISTS vector;
      CREATE EXTENSION IF NOT EXISTS pg_trgm;
      CREATE EXTENSION IF NOT EXISTS unaccent;
      CREATE EXTENSION IF NOT EXISTS btree_gin;
    '';
  };

  # ─── PROCESSES ─────────────────────────────────────────────────────────────
  processes = {
    # Metabase BI — http://localhost:3100
    # Uses wrapper script with auto-init env vars
    metabase.exec = "${metabaseStart}/bin/metabase-start";
  };

  # ─── ENVIRONMENT VARIABLES ─────────────────────────────────────────────────
  env = {
    # psql/libpq connect via Unix socket using PGHOST + PGPORT (set by devenv)
    DATABASE_URL  = "postgresql:///cultguard";
    # Nix-managed npm dependency tree, linked into ./node_modules by repo commands.
    CULTGUARD_NPM_DEPS       = "${npmDeps}";
    # Keep model/tokenizer caches inside this devenv — nothing leaks to ~/.cache
    HF_HOME                  = "${config.devenv.state}/models/huggingface";
    TRANSFORMERS_CACHE       = "${config.devenv.state}/models/huggingface";
    # Chromium user data for FB scraper (persistent login session)
    CHROMIUM_USER_DATA_DIR   = "${config.devenv.state}/chromium";
    # Project-local privacy desktop runtime defaults
    PRIVACY_STACK_INSTANCE   = "1";
    PRIVACY_REMOTE_BACKEND   = "vnc";
    PRIVACY_TIMEZONE         = "Europe/London";
    PRIVACY_RESOLUTION       = "1920x1080";
    PRIVACY_BIND_HOST        = "127.0.0.1";
    PRIVACY_STACK_STATE_DIR  = "${config.devenv.state}/privacy-stack";
  };

  # ─── SCRIPTS ───────────────────────────────────────────────────────────────
  # One-time setup and daily CLI tools
  scripts = {
    # Initial database setup — run once or when schema changes
    db-setup.exec = ''
      set -e
      SOCKET_DIR="$PGHOST"
      SOCKET="$SOCKET_DIR/.s.PGSQL.$PGPORT"

      echo "→ Waiting for PostgreSQL socket at $SOCKET..."
      for i in $(seq 1 30); do
        [ -S "$SOCKET" ] && break
        sleep 1
        echo "  ...($i)"
      done
      [ -S "$SOCKET" ] || { echo "✗ PostgreSQL socket not found after 30s"; exit 1; }

      echo "→ Applying schema..."
      psql cultguard < "$DEVENV_ROOT/data/schema.sql"

      if [ -f "$DEVENV_ROOT/data/osint.db" ]; then
        echo "  (legacy osint.db found — migration scripts are archival Python; run manually if needed)"
      fi

      echo ""
      echo "✓ Setup complete. Run 'db-stats' to verify."
    '';

    # Dump database to filesystem (backup/restore)
    db-dump.exec = ''
      DUMP_FILE="$DEVENV_ROOT/data/cultguard-$(date +%Y%m%d-%H%M%S).sql"
      echo "→ Dumping cultguard database to $DUMP_FILE..."
      # PGHOST and PGPORT are set by devenv shell
      pg_dump -h "$PGHOST" -p "$PGPORT" cultguard > "$DUMP_FILE"
      if [ -s "$DUMP_FILE" ]; then
        echo "✓ Dump complete: $DUMP_FILE ($(wc -l < "$DUMP_FILE") lines)"
      else
        echo "✗ Dump failed - empty file"
      fi
    '';

    db-restore.exec = ''
      if [ -z "$1" ] || [ ! -f "$1" ]; then
        echo "Usage: db-restore <dump_file.sql>"
        echo "Example: db-restore data/cultguard-20260325-120000.sql"
        exit 1
      fi
      echo "→ Restoring from $1..."
      psql cultguard < "$1"
      echo "✓ Restore complete."
    '';

    # TypeScript / Node workflows (Nix-managed npm deps; no npm install required)
    typecheck.exec = ''
      ${ensureNodeDeps}
      cd "$DEVENV_ROOT"
      exec tsc --noEmit
    '';

    # Embeddings — run after new content ingestion
    db-embed.exec = ''
      mkdir -p "$HF_HOME"
      echo "→ Running embedding pipeline..."
      echo "  Models cache: $HF_HOME"
      echo "  (First run downloads ONNX models — bge-m3 + CLIP)"
      ${runTs "src/embed.ts"}
    '';

    # Quick DB access
    db-shell.exec = ''
      psql cultguard
    '';

    db-stats.exec = ''
      psql cultguard -c "
        SELECT table_name,
               (SELECT reltuples::bigint FROM pg_class WHERE relname = table_name) AS approx_rows
        FROM information_schema.tables
        WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
        ORDER BY table_name;
      "
    '';

    # Query and ingestion (TypeScript)
    search.exec = runTs "src/search.ts";

    ingest.exec = runTs "src/ingest.ts";

    # Facebook page scraper — connects to pre-existing Chromium via CDP
    fb-scrape.exec = runTs "src/fb-scrape.ts";

    # Autonomous agents
    agent-monitor.exec = runTs "src/agents/facebook-monitor.ts";
    agent-analyzer.exec = runTs "src/agents/content-analyzer.ts";
    agent-alert.exec = runTs "src/agents/alert-system.ts";
    agent-collector.exec = runTs "src/agents/evidence-collector.ts";

    # Launch Chromium with CDP debug port for fb-scrape
    fb-chrome.exec = ''
      CHROME_DATA="$CHROMIUM_USER_DATA_DIR"
      mkdir -p "$CHROME_DATA"
      echo "→ Launching Chromium with remote debugging on port 9222"
      echo "  User data: $CHROME_DATA"
      echo "  Log in to Facebook in the browser, then run fb-scrape in another terminal."
      echo ""
      exec chromium \
        --remote-debugging-port=9222 \
        --user-data-dir="$CHROME_DATA" \
        --no-first-run \
        --no-default-browser-check \
        "https://www.facebook.com"
    '';

    # Project-local privacy desktop stack
    privacy-profile-create.exec = ''
      exec ${lib.getExe privacy.privacyProfileCreate} "$@"
    '';

    privacy-profile-list.exec = ''
      exec ${lib.getExe privacy.privacyProfileList} "$@"
    '';

    privacy-profile-show.exec = ''
      exec ${lib.getExe privacy.privacyProfileShow} "$@"
    '';

    privacy-profile-delete.exec = ''
      exec ${lib.getExe privacy.privacyProfileDelete} "$@"
    '';

    privacy-profile-attach.exec = ''
      exec ${lib.getExe privacy.privacyProfileAttach} "$@"
    '';

    privacy-profile-detach.exec = ''
      exec ${lib.getExe privacy.privacyProfileDetach} "$@"
    '';

    privacy-browser-up.exec = ''
      exec ${lib.getExe privacy.privacyBrowserUp} "$@"
    '';

    privacy-browser-down.exec = ''
      exec ${lib.getExe privacy.privacyBrowserDown} "$@"
    '';

    privacy-browser-status.exec = ''
      exec ${lib.getExe privacy.privacyBrowserStatus} "$@"
    '';

    privacy-browser-test.exec = ''
      exec ${lib.getExe privacy.privacyBrowserTest} "$@"
    '';

    privacy-browser-test-all.exec = ''
      exec ${lib.getExe privacy.privacyBrowserTestAll} "$@"
    '';

    privacy-secrets-render.exec = ''
      exec ${lib.getExe privacy.privacySecretsRender} "$@"
    '';

    sops-add-machine.exec = ''
      exec ${lib.getExe privacy.sopsAddMachine} "$@"
    '';
  };

  # ─── ENTER SHELL HOOK ──────────────────────────────────────────────────────
  enterShell = ''
    echo ""
    echo "  cultguard-agents dev environment"
    echo "  ─────────────────────────────"
    echo "  DB socket:  $PGHOST/.s.PGSQL.$PGPORT"
    echo "  Metabase:   http://localhost:3100  (after devenv up)"
    echo "  Node deps:  Nix-managed from package-lock.json"
    echo ""
    echo "  Tasks (one-time setup):"
    echo "    db-setup      # Initialize DB + schema"
    echo "    db-dump       # Backup DB to filesystem"
    echo "    db-embed      # Generate embeddings (ONNX)"
    echo "    typecheck     # TypeScript check via Nix-managed deps"
    echo "    pi            # Repo-local Pi coding agent CLI (0.65.0)"
    echo ""
    echo "  Scripts (daily use):"
    echo "    db-shell      # psql shell"
    echo "    db-stats      # Row counts"
    echo "    search        # Semantic/FTS search"
    echo "    ingest        # Add content/media"
    echo "    fb-chrome     # Launch Chromium with CDP debug port"
    echo "    fb-scrape     # Facebook page scraper"
    echo "    agent-monitor # Continuous monitoring agent"
    echo "    agent-analyzer# Content analysis agent"
    echo "    agent-alert   # Alerting agent"
    echo "    agent-collector # Evidence collection agent"
    echo "    privacy-profile-create/list/show   # manage self-contained browser profiles"
    echo "    privacy-profile-attach/detach      # attach profiles to browser instances"
    echo "    privacy-profile-delete             # remove an unused browser profile"
    echo "    privacy-browser-up/down/status     # wireproxy + x11vnc + chromium"
    echo "    privacy-browser-test               # one Mullvad config, test in browser"
    echo "    privacy-browser-test-all           # test all Mullvad configs in browser"
    echo "    privacy-secrets-render             # Decrypt a project-local secret"
    echo ""
  '';
}
