#!/usr/bin/env bash
# Delete a user by username from the Docker (production) SQLite DB.
# Run this on the prod server next to docker-compose.yml.
#
# Usage:
#   ./scripts/xdocker-delete-user.sh <username>
#   ./scripts/xdocker-delete-user.sh <username> --yes   # skip confirmation
#
# Removes the User and related data (inventory, transactions, deposits,
# case-key progress, duel rooms they created). Nulls jackpot/duel winner
# pointers that referenced them.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [[ -f "$SCRIPT_DIR/../docker-compose.yml" ]]; then
  ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
elif [[ -f "$SCRIPT_DIR/docker-compose.yml" ]]; then
  ROOT="$SCRIPT_DIR"
else
  echo "Error: docker-compose.yml not found near $SCRIPT_DIR" >&2
  exit 1
fi
cd "$ROOT"

ENV_FILE="${ENV_FILE:-.env.prod}"
COMPOSE=(docker compose)
if [[ -f "$ENV_FILE" ]]; then
  COMPOSE=(docker compose --env-file "$ENV_FILE")
fi

SERVICE="${SERVICE:-casegambling}"
USERNAME="${1:-}"
ASSUME_YES=0

if [[ -z "$USERNAME" || "$USERNAME" == "-h" || "$USERNAME" == "--help" ]]; then
  echo "Usage: $0 <username> [--yes]" >&2
  echo "Example: $0 badplayer" >&2
  echo "         $0 badplayer --yes" >&2
  exit 1
fi

shift || true
for arg in "$@"; do
  case "$arg" in
    --yes|-y) ASSUME_YES=1 ;;
    *)
      echo "Error: unknown argument: $arg" >&2
      exit 1
      ;;
  esac
done

if ! command -v docker >/dev/null 2>&1; then
  echo "Error: docker not found" >&2
  exit 1
fi

if [[ -z "$("${COMPOSE[@]}" ps -q --status running "$SERVICE" 2>/dev/null || true)" ]]; then
  echo "Error: compose service '$SERVICE' is not running" >&2
  echo "Tip: docker compose --env-file .env.prod up -d" >&2
  exit 1
fi

run_node() {
  local mode="$1"
  "${COMPOSE[@]}" exec -T \
    -e DEL_USERNAME="$USERNAME" \
    -e DEL_MODE="$mode" \
    "$SERVICE" node <<'NODE'
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();

(async () => {
  const username = process.env.DEL_USERNAME;
  const mode = process.env.DEL_MODE;
  const user = await prisma.user.findUnique({
    where: { username },
    select: {
      id: true,
      username: true,
      role: true,
      balance: true,
      osuBalance: true,
      createdAt: true,
      _count: {
        select: {
          inventory: true,
          transactions: true,
          jackpotDeposits: true,
          duelDeposits: true,
          duelRoomsCreated: true,
          caseKeyProgress: true,
        },
      },
    },
  });

  if (!user) {
    console.error(`Error: no user with username '${username}'`);
    process.exit(2);
  }

  if (mode === 'info') {
    console.log(`id:           ${user.id}`);
    console.log(`username:     ${user.username}`);
    console.log(`role:         ${user.role}`);
    console.log(`balance:      ${user.balance.toString()}`);
    console.log(`osuBalance:   ${user.osuBalance}`);
    console.log(`createdAt:    ${user.createdAt.toISOString()}`);
    console.log(`inventory:    ${user._count.inventory}`);
    console.log(`transactions: ${user._count.transactions}`);
    console.log(`jackpot deps: ${user._count.jackpotDeposits}`);
    console.log(`duel deps:    ${user._count.duelDeposits}`);
    console.log(`duel rooms:   ${user._count.duelRoomsCreated}`);
    console.log(`case keys:    ${user._count.caseKeyProgress}`);
    if (user.role === 'admin') {
      console.log('WARNING: role=admin');
    }
    process.exit(0);
  }

  if (mode !== 'delete') {
    console.error(`Unknown mode: ${mode}`);
    process.exit(1);
  }

  await prisma.$transaction(async (tx) => {
    // Optional FKs without onDelete Cascade
    await tx.jackpotRound.updateMany({
      where: { winnerUserId: user.id },
      data: { winnerUserId: null },
    });
    await tx.duelRoom.updateMany({
      where: { winnerUserId: user.id },
      data: { winnerUserId: null },
    });

    // Deposits reference InventoryItem — remove before user/inventory cascade
    await tx.jackpotDeposit.deleteMany({ where: { userId: user.id } });
    await tx.duelDeposit.deleteMany({ where: { userId: user.id } });

    // Rooms created by this user (other deposits in those rooms cascade with room)
    await tx.duelRoom.deleteMany({ where: { creatorId: user.id } });

    await tx.user.delete({ where: { id: user.id } });
  });

  console.log(`Deleted user id=${user.id} username=${user.username}`);
})().catch((e) => {
  console.error(e);
  process.exit(1);
}).finally(() => prisma.$disconnect());
NODE
}

echo "==> Looking up user '$USERNAME' …"
set +e
INFO_OUT="$(run_node info 2>&1)"
INFO_RC=$?
set -e
echo "$INFO_OUT"
if [[ "$INFO_RC" -ne 0 ]]; then
  exit "$INFO_RC"
fi

if [[ "$ASSUME_YES" -ne 1 ]]; then
  echo ""
  printf "Delete user '%s' permanently? [y/N] " "$USERNAME"
  read -r REPLY
  case "$REPLY" in
    y|Y|yes|YES) ;;
    *)
      echo "Aborted."
      exit 0
      ;;
  esac
fi

echo "==> Deleting …"
run_node delete
echo "==> Done."
