{ pkgs, ... }:

let
  cleanSrc = pkgs.lib.cleanSourceWith {
    src = ./.;
    filter = path: type:
      let
        base = builtins.baseNameOf path;
      in
        !(builtins.elem base [
          "node_modules"
          "dist"
          ".devenv"
          ".direnv"
          ".env"
          ".run"
        ]);
  };

  txocapApp = pkgs.buildNpmPackage {
    pname = "txocap";
    version = "0.1.1";
    src = cleanSrc;
    npmDepsHash = "sha256-1NMOwul6IHiboa1jF6UtIB7ZTQRc1BE+HegP0ZDfPsQ=";
    npmBuildScript = "build";

    installPhase = ''
      runHook preInstall

      mkdir -p "$out/libexec/txocap" "$out/bin"
      cp -r dist package.json "$out/libexec/txocap/"
      cp -r node_modules "$out/libexec/txocap/node_modules"

      write_node_wrapper() {
        local name="$1"
        local entry="$2"
        cat > "$out/bin/$name" <<EOF
#!${pkgs.bash}/bin/bash
set -euo pipefail
cd "''${TXOCAP_REPO_ROOT:-\$PWD}"
exec ${pkgs.nodejs_22}/bin/node "$out/libexec/txocap/$entry" "\$@"
EOF
        chmod +x "$out/bin/$name"
      }

      write_text_wrapper() {
        local name="$1"
        local body="$2"
        cat > "$out/bin/$name" <<EOF
#!${pkgs.bash}/bin/bash
set -euo pipefail
$body
EOF
        chmod +x "$out/bin/$name"
      }

      write_node_wrapper txocap-dashboard dist/runners/dashboard.js
      write_node_wrapper txocap-discover-btc dist/scripts/discover-btc.js
      write_node_wrapper txocap-account-check dist/scripts/account-check.js
      write_node_wrapper txocap-demo-fund dist/scripts/demo-fund.js
      write_node_wrapper txocap-order-place dist/scripts/place-demo-order.js
      write_node_wrapper txocap-demo-benchmark dist/runners/demo-benchmark.js
      write_node_wrapper txocap-momentum-demo dist/runners/momentum-demo.js
      write_node_wrapper txocap-edge-search dist/research/edge-search.js

      write_text_wrapper txocap-replay 'exec ${pkgs.nodejs_22}/bin/node "$out/libexec/txocap/dist/runners/replay.js" --replay "$@"'

      cat > "$out/bin/txocap-build" <<EOF
#!${pkgs.bash}/bin/bash
set -euo pipefail
echo "txocap is already built in the Nix store: $out"
EOF
      chmod +x "$out/bin/txocap-build"

      runHook postInstall
    '';
  };

  enterRepo = ''
    repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
    cd "$repo_root"

    export TXOCAP_REPO_ROOT="$repo_root"
    export TXOCAP_DEVENV_STATE_ROOT="$repo_root/.devenv/state"
    export TXOCAP_DEVENV_TMP_ROOT="$TXOCAP_DEVENV_STATE_ROOT/tmp"
    export TXOCAP_XDG_ROOT="$TXOCAP_DEVENV_STATE_ROOT/xdg"
    export TMPDIR="$TXOCAP_DEVENV_TMP_ROOT"
    export XDG_CACHE_HOME="$TXOCAP_XDG_ROOT/cache"
    export XDG_CONFIG_HOME="$TXOCAP_XDG_ROOT/config"
    export XDG_STATE_HOME="$TXOCAP_XDG_ROOT/state"

    mkdir -p \
      "$TXOCAP_DEVENV_STATE_ROOT" \
      "$TXOCAP_DEVENV_TMP_ROOT" \
      "$XDG_CACHE_HOME" \
      "$XDG_CONFIG_HOME" \
      "$XDG_STATE_HOME"
  '';
in
{
  dotenv.enable = true;

  packages = with pkgs; [
    bashInteractive
    git
    jq
    nodejs_22
    txocapApp
  ];

  enterShell = enterRepo + ''
    echo "txocap devenv ready."
    echo "Dashboard:       txocap-dashboard"
    echo "Replay:          txocap-replay <session-dir>"
    echo "Compare:         node dist/research/compare-profiles.js"
    echo "Edge search:     txocap-edge-search"
    echo "Demo benchmark:  txocap-demo-benchmark"
    echo "Discover:        txocap-discover-btc"
    echo "Account:         txocap-account-check"
    echo "Fund demo:       txocap-demo-fund USDT:10000 BTC:1"
    echo "Order:           txocap-order-place --side Buy --qty 0.001 --category linear --symbol BTCUSDT"
    echo "Build ref:       txocap-build"
    echo "Copy .env.example -> .env for Bybit demo credentials."
  '';

  enterTest = enterRepo + ''
    set -euo pipefail
    command -v txocap-dashboard
    command -v txocap-replay
    command -v txocap-demo-benchmark
    command -v txocap-edge-search
    command -v txocap-discover-btc
    command -v txocap-account-check
    txocap-build
  '';
}
