#!/usr/bin/env bash
# Import SQLite DB (+ uploads) INTO Docker (production / compose).
# Run this on the machine that runs docker compose.
#
# Usage:
#   ./scripts/xdocker-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS
#   ./scripts/xdocker-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS.tar.gz
#   ./scripts/xdocker-db-import.sh ./backups/….tar.gz <username>   # player-only merge
#
# Expects a backup from docker-db-export.sh or local-db-export.sh
# (prod.db or dev.db + uploads/).
#
# Docker paths (see docker-compose.yml):
#   DATABASE_URL=file:/data/prod.db
#   uploads → /app/uploads
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

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 first: ./scripts/docker-db-export.sh  (or local-db-export.sh)" >&2
  exit 1
fi

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

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

cd "$ROOT"

ENV_FILE="${ENV_FILE:-.env.prod}"
COMPOSE=(docker compose)
if [[ -f "$ENV_FILE" ]]; then
  COMPOSE=(docker compose --env-file "$ENV_FILE")
elif [[ -f ".env.prod.example" ]]; then
  echo "Warning: $ENV_FILE missing — using compose defaults." >&2
  echo "         Copy .env.prod.example → .env.prod for production settings." >&2
fi

SERVICE="${SERVICE:-casegambling}"

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

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

copy_player_avatar_docker() {
  local avatar_url="$1"
  local uploads_src="$2"
  [[ -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
    "${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \
      "mkdir -p /app/uploads/$(dirname "$rel")" >/dev/null
    "${COMPOSE[@]}" cp "$src_file" "$SERVICE:/app/uploads/$rel"
    echo "==> Copied avatar upload: $rel"
  fi
}

if ! command -v docker >/dev/null 2>&1; then
  echo "Error: docker not found" >&2
  exit 1
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 produced by docker-db-export.sh / local-db-export.sh" >&2
  exit 1
fi

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

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

echo "==> Ensuring compose service exists"
"${COMPOSE[@]}" up -d --no-start "$SERVICE" >/dev/null

# ── Player-only merge into existing Docker DB ────────────────────────────────
if [[ -n "$USERNAME" ]]; then
  if [[ ! -x "$MERGE_PLAYER_SCRIPT" ]]; then
    echo "Error: merge helper missing or not executable: $MERGE_PLAYER_SCRIPT" >&2
    exit 1
  fi
  if ! command -v sqlite3 >/dev/null 2>&1; then
    echo "Error: sqlite3 is required on the host for player-only import" >&2
    exit 1
  fi

  echo "==> Stopping $SERVICE (safe SQLite merge)"
  "${COMPOSE[@]}" stop "$SERVICE" >/dev/null 2>&1 || true

  WORK="$(mktemp -d)"
  TARGET_DB="$WORK/prod.db"

  echo "==> Fetching current /data/prod.db"
  if ! "${COMPOSE[@]}" cp "$SERVICE:/data/prod.db" "$TARGET_DB" 2>/dev/null; then
    echo "Error: could not copy /data/prod.db from $SERVICE" >&2
    echo "Tip: run a full import once first so the volume has a database." >&2
    exit 1
  fi
  "${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \
    'rm -f /data/prod.db-wal /data/prod.db-shm' >/dev/null

  "$MERGE_PLAYER_SCRIPT" "$DB" "$TARGET_DB" "$USERNAME"

  echo "==> Writing merged database → /data/prod.db"
  "${COMPOSE[@]}" cp "$TARGET_DB" "$SERVICE:/data/prod.db"

  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_docker "${AVATAR_URL:-}" "$SRC/uploads"
  fi

  echo "==> Starting $SERVICE"
  "${COMPOSE[@]}" start "$SERVICE" 2>/dev/null || "${COMPOSE[@]}" up -d "$SERVICE"

  HOST_PORT_VAL="${HOST_PORT:-}"
  if [[ -z "$HOST_PORT_VAL" && -f "$ENV_FILE" ]]; then
    HOST_PORT_VAL="$(grep -E '^HOST_PORT=' "$ENV_FILE" 2>/dev/null | cut -d= -f2- | tr -d '"' || true)"
  fi
  HOST_PORT_VAL="${HOST_PORT_VAL:-3009}"

  echo "==> Done (player-only)."
  echo "    App:  http://localhost:${HOST_PORT_VAL}"
  echo "    Logs: ${COMPOSE[*]} logs -f --tail=50"
  exit 0
fi

# ── Full import (replace Docker DB + uploads) ────────────────────────────────
echo "==> Stopping $SERVICE (safe SQLite replace)"
"${COMPOSE[@]}" stop "$SERVICE" >/dev/null 2>&1 || true

echo "==> Clearing old SQLite sidecars on volume"
"${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \
  'rm -f /data/prod.db-wal /data/prod.db-shm' >/dev/null

echo "==> Importing database ← $DB"
"${COMPOSE[@]}" cp "$DB" "$SERVICE:/data/prod.db"

WAL=""
SHM=""
[[ -f "$SRC/prod.db-wal" ]] && WAL="$SRC/prod.db-wal"
[[ -z "$WAL" && -f "$SRC/dev.db-wal" ]] && WAL="$SRC/dev.db-wal"
[[ -f "$SRC/prod.db-shm" ]] && SHM="$SRC/prod.db-shm"
[[ -z "$SHM" && -f "$SRC/dev.db-shm" ]] && SHM="$SRC/dev.db-shm"

if [[ -n "$WAL" ]]; then
  "${COMPOSE[@]}" cp "$WAL" "$SERVICE:/data/prod.db-wal"
fi
if [[ -n "$SHM" ]]; then
  "${COMPOSE[@]}" cp "$SHM" "$SERVICE:/data/prod.db-shm"
fi

if [[ -d "$SRC/uploads" ]]; then
  echo "==> Importing uploads"
  "${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \
    'rm -rf /app/uploads/* /app/uploads/.[!.]* 2>/dev/null; mkdir -p /app/uploads' >/dev/null
  "${COMPOSE[@]}" cp "$SRC/uploads/." "$SERVICE:/app/uploads/"
fi

echo "==> Starting $SERVICE"
"${COMPOSE[@]}" start "$SERVICE" 2>/dev/null || "${COMPOSE[@]}" up -d "$SERVICE"

HOST_PORT_VAL="${HOST_PORT:-}"
if [[ -z "$HOST_PORT_VAL" && -f "$ENV_FILE" ]]; then
  HOST_PORT_VAL="$(grep -E '^HOST_PORT=' "$ENV_FILE" 2>/dev/null | cut -d= -f2- | tr -d '"' || true)"
fi
HOST_PORT_VAL="${HOST_PORT_VAL:-3009}"

echo "==> Done."
echo "    App:  http://localhost:${HOST_PORT_VAL}"
echo "    Logs: ${COMPOSE[*]} logs -f --tail=50"
