#!/usr/bin/env bash
set -euo pipefail

APP_DIR="$(cd "$(dirname "$0")" && pwd)"

# ── Decrypt secrets ───────────────────────────────────────

if ! command -v sops &>/dev/null; then
    echo "ERROR: sops not found — run infra/setup_server.sh first"
    exit 1
fi

sops --input-type dotenv --output-type dotenv -d "${APP_DIR}/.env.prod.sops" > "${APP_DIR}/.env"
chmod 600 "${APP_DIR}/.env"

COMPOSE="docker compose -f docker-compose.prod.yml"
LIVE_FILE=".live-slot"
ROUTER_CONF="router/default.conf"

# ── Determine slots ─────────────────────────────────────────

CURRENT=$(cat "$LIVE_FILE" 2>/dev/null || echo "none")

if [ "$CURRENT" = "blue" ]; then
    TARGET="green"
else
    TARGET="blue"
fi

echo "==> Current: $CURRENT → Deploying: $TARGET"

# ── Build ───────────────────────────────────────────────────

echo "==> Building $TARGET..."
$COMPOSE --profile "$TARGET" build

# ── Backup DB before migration ────────────────────────────────

BACKUP_TAG="pre-deploy-$(date +%Y%m%d-%H%M%S)"
echo "==> Backing up database (${BACKUP_TAG})..."
$COMPOSE run --rm --entrypoint "" "${TARGET}-app" \
    sh -c "cp /app/data/app.db /app/data/app.db.${BACKUP_TAG} 2>/dev/null || true"

# ── Migrate ─────────────────────────────────────────────────

echo "==> Running migrations..."
$COMPOSE --profile "$TARGET" run --rm "${TARGET}-app" \
    python -m padelnomics.migrations.migrate

# ── Ensure router is healthy before waiting ──────────────────
# nginx -t resolves upstream hostnames — if the config points to a stopped
# slot, the health check fails. Write config for the CURRENT live slot
# (which is still running) so the router stays healthy during --wait.

_write_router_conf() {
    local SLOT="$1"
    mkdir -p "$(dirname "$ROUTER_CONF")"
    cat > "$ROUTER_CONF" <<NGINX
upstream app {
    server ${SLOT}-app:5000;
}

server {
    listen 80;

    location / {
        proxy_pass http://app;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto;
    }
}
NGINX
}

if [ "$CURRENT" != "none" ]; then
    echo "==> Resetting router to current slot ($CURRENT)..."
    _write_router_conf "$CURRENT"
    $COMPOSE restart router
fi

# ── Start & health check ───────────────────────────────────

echo "==> Starting $TARGET (waiting for health check)..."
if ! $COMPOSE --profile "$TARGET" up -d --wait; then
    echo "!!! Health check failed — dumping logs"
    echo "--- ${TARGET}-app logs ---"
    $COMPOSE --profile "$TARGET" logs --tail=60 "${TARGET}-app" 2>&1 || true
    echo "--- router logs ---"
    $COMPOSE logs --tail=10 router 2>&1 || true
    echo "--- litestream logs ---"
    $COMPOSE logs --tail=10 litestream 2>&1 || true
    echo "!!! Rolling back"
    $COMPOSE stop "${TARGET}-app" "${TARGET}-worker" "${TARGET}-scheduler"
    LATEST=$($COMPOSE run --rm --entrypoint "" "${TARGET}-app" \
        sh -c "ls -t /app/data/app.db.pre-deploy-* 2>/dev/null | head -1")
    if [ -n "$LATEST" ]; then
        echo "==> Restoring database from ${LATEST}..."
        $COMPOSE run --rm --entrypoint "" "${TARGET}-app" \
            sh -c "cp '${LATEST}' /app/data/app.db"
    fi
    exit 1
fi

# ── Write router config and reload (new slot is healthy) ────

echo "==> Switching router to $TARGET..."
_write_router_conf "$TARGET"
$COMPOSE exec router nginx -s reload

# ── Cleanup old pre-deploy backups (keep last 3) ─────────────

$COMPOSE run --rm --entrypoint "" "${TARGET}-app" \
    sh -c "ls -t /app/data/app.db.pre-deploy-* 2>/dev/null | tail -n +4 | xargs rm -f" || true

# ── Stop old slot ───────────────────────────────────────────

if [ "$CURRENT" != "none" ]; then
    echo "==> Stopping $CURRENT..."
    $COMPOSE stop "${CURRENT}-app" "${CURRENT}-worker" "${CURRENT}-scheduler"
fi

# ── Record live slot ────────────────────────────────────────

echo "$TARGET" > "$LIVE_FILE"
echo "==> Deployed $TARGET successfully!"
