#!/usr/bin/env bash
# Import SQLite DB (+ uploads) into the LOCAL project
# (server/prisma/dev.db + server/uploads/).
#
# Usage:
#   ./scripts/local-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS
#   ./scripts/local-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS.tar.gz
#   ./scripts/local-db-import.sh ./backups/….tar.gz <username>   # player-only merge
#
# Typical flow (prod → laptop):
#   # on prod:
#   ./scripts/docker-db-export.sh
#   # copy the .tar.gz here, then:
#   ./scripts/local-db-import.sh ./backups/casegambling-….tar.gz
#   # or only one player into the existing local DB:
#   ./scripts/local-db-import.sh ./backups/casegambling-….tar.gz SomePlayer
#
# Stop `npm run dev` before importing so SQLite is not locked.
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
MERGE_PLAYER_SCRIPT="$ROOT/scripts/merge-player-db.sh"

if [[ -z "${1:-}" || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  echo "Usage: $0 <backup-dir-or-tar.gz> [username]" >&2
  echo "Example: $0 ./backups/casegambling-20260116-203000.tar.gz" >&2
  echo "         $0 ./backups/casegambling-20260116-203000.tar.gz SomePlayer" >&2
  echo "Create a backup from Docker: ./scripts/docker-db-export.sh" >&2
  exit 1
fi

BACKUP_ARG="$1"
USERNAME="${2:-}"

# Resolve backup path from the caller's cwd
if [[ "$BACKUP_ARG" = /* ]]; then
  SRC="$BACKUP_ARG"
else
  SRC="$(pwd)/$BACKUP_ARG"
fi

LOCAL_DB="${LOCAL_DB:-$ROOT/server/prisma/dev.db}"
LOCAL_UPLOADS="${LOCAL_UPLOADS:-$ROOT/server/uploads}"

TMP=""
cleanup() {
  if [[ -n "$TMP" && -d "$TMP" ]]; then
    rm -rf "$TMP"
  fi
}
trap cleanup EXIT

is_archive() {
  case "$1" in
    *.tar.gz|*.tgz) return 0 ;;
    *) return 1 ;;
  esac
}

copy_player_avatar() {
  local avatar_url="$1"
  local uploads_src="$2"
  local uploads_dst="$3"
  [[ -z "$avatar_url" || ! -d "$uploads_src" ]] && return 0
  local rel="${avatar_url#/}"
  rel="${rel#uploads/}"
  rel="${rel#./}"
  case "$rel" in
    ''|http:*|https:*|*..*) return 0 ;;
  esac
  local src_file="$uploads_src/$rel"
  if [[ -f "$src_file" ]]; then
    mkdir -p "$uploads_dst/$(dirname "$rel")"
    cp -f "$src_file" "$uploads_dst/$rel"
    echo "==> Copied avatar upload: $rel"
  fi
}

if [[ -f "$SRC" ]] && is_archive "$SRC"; then
  echo "==> Extracting $(basename "$SRC")"
  TMP="$(mktemp -d)"
  tar -xzf "$SRC" -C "$TMP"
  mapfile -t DIRS < <(find "$TMP" -mindepth 1 -maxdepth 1 -type d | sort)
  if [[ ${#DIRS[@]} -ge 1 ]]; then
    SRC="${DIRS[0]}"
  else
    SRC="$TMP"
  fi
elif [[ -f "$SRC" ]]; then
  echo "Error: not a directory or .tar.gz archive: $SRC" >&2
  exit 1
fi

if [[ ! -d "$SRC" ]]; then
  echo "Error: backup not found: $SRC" >&2
  echo "Pass a folder or a .tar.gz from docker-db-export.sh / local-db-export.sh" >&2
  exit 1
fi

DB=""
for candidate in "$SRC/dev.db" "$SRC/prod.db"; do
  if [[ -f "$candidate" ]]; then
    DB="$candidate"
    break
  fi
done

if [[ -z "$DB" ]]; then
  echo "Error: no dev.db or prod.db in $SRC" >&2
  ls -la "$SRC" >&2 || true
  exit 1
fi

# ── Player-only merge into existing local DB ─────────────────────────────────
if [[ -n "$USERNAME" ]]; then
  if [[ ! -f "$LOCAL_DB" ]]; then
    echo "Error: local DB not found: $LOCAL_DB" >&2
    echo "Tip: run a full import first (without username), or start the app once." >&2
    exit 1
  fi
  if [[ ! -x "$MERGE_PLAYER_SCRIPT" ]]; then
    echo "Error: merge helper missing or not executable: $MERGE_PLAYER_SCRIPT" >&2
    exit 1
  fi

  # Drop WAL/SHM so we merge against the real file contents
  rm -f "${LOCAL_DB}-wal" "${LOCAL_DB}-shm"

  "$MERGE_PLAYER_SCRIPT" "$DB" "$LOCAL_DB" "$USERNAME"
  AVATAR_URL="$(sqlite3 "$DB" "SELECT avatarUrl FROM User WHERE username = '${USERNAME//\'/\'\'}' LIMIT 1;" 2>/dev/null || true)"
  if [[ -d "$SRC/uploads" ]]; then
    copy_player_avatar "${AVATAR_URL:-}" "$SRC/uploads" "$LOCAL_UPLOADS"
  fi

  echo "==> Done (player-only)."
  echo "    db: $LOCAL_DB"
  echo "    Tip: stop npm run dev before import if the DB was locked; then restart:"
  echo "         npm run dev"
  exit 0
fi

# ── Full import (replace local DB + uploads) ─────────────────────────────────
mkdir -p "$(dirname "$LOCAL_DB")"

echo "==> Importing database → $LOCAL_DB"
echo "    source: $DB"

# Drop local WAL/SHM so the new file is the sole source of truth
rm -f "${LOCAL_DB}-wal" "${LOCAL_DB}-shm"

if command -v sqlite3 >/dev/null 2>&1; then
  # Normalize into a clean single-file DB
  sqlite3 "$DB" ".backup '$LOCAL_DB'"
else
  cp -f "$DB" "$LOCAL_DB"
  WAL=""
  SHM=""
  [[ -f "$SRC/dev.db-wal" ]] && WAL="$SRC/dev.db-wal"
  [[ -z "$WAL" && -f "$SRC/prod.db-wal" ]] && WAL="$SRC/prod.db-wal"
  [[ -f "$SRC/dev.db-shm" ]] && SHM="$SRC/dev.db-shm"
  [[ -z "$SHM" && -f "$SRC/prod.db-shm" ]] && SHM="$SRC/prod.db-shm"
  [[ -n "$WAL" ]] && cp -f "$WAL" "${LOCAL_DB}-wal"
  [[ -n "$SHM" ]] && cp -f "$SHM" "${LOCAL_DB}-shm"
fi

if [[ -d "$SRC/uploads" ]]; then
  echo "==> Importing uploads → $LOCAL_UPLOADS"
  mkdir -p "$LOCAL_UPLOADS"
  # Keep .gitkeep if present; replace other files
  find "$LOCAL_UPLOADS" -mindepth 1 ! -name '.gitkeep' -exec rm -rf {} + 2>/dev/null || true
  cp -a "$SRC/uploads"/. "$LOCAL_UPLOADS/" 2>/dev/null || true
fi

DB_SIZE="$(du -h "$LOCAL_DB" | awk '{print $1}')"
UPLOAD_COUNT="$(find "$LOCAL_UPLOADS" -type f ! -name '.gitkeep' 2>/dev/null | wc -l | tr -d ' ')"

echo "==> Done."
echo "    db: $LOCAL_DB ($DB_SIZE)"
echo "    uploads files: $UPLOAD_COUNT"
echo "    Tip: stop npm run dev before import if the DB was locked; then restart:"
echo "         npm run db:push && npm run dev"
