#!/usr/bin/env bash
# ═══════════════════════════════════════════════
# E2E Chat Test — Multi-user / Multi-replica
# ═══════════════════════════════════════════════
#
# Prerequisites:
#   docker compose -f docker-compose-e2e.yml up --build -d
#
# Tests:
#   1. Auth as alice + bob
#   2. Alice creates conversation, adds bob
#   3. Alice sends message via REST
#   4. Bob reads messages, verifies receipt
#   5. Cross-replica: send via replica-1, read via replica-2
#   6. WebSocket realtime delivery (via ws-listener)
#
# Exit codes: 0 = pass, 1 = failure
set -euo pipefail

LB="http://localhost:3000"
R1="http://localhost:8081"
R2="http://localhost:8082"
MAX_RETRIES=30

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

pass=0
fail=0

ok()   { pass=$((pass + 1)); echo -e "  ${GREEN}✓${NC} $1"; }
fail() { fail=$((fail + 1)); echo -e "  ${RED}✗${NC} $1"; }

# ── Wait for LB ─────────────────────────────

echo -e "${YELLOW}Waiting for load balancer...${NC}"
for i in $(seq 1 $MAX_RETRIES); do
  if curl -sf "$LB/api/v1/auth/login" -o /dev/null 2>/dev/null || \
     curl -sf "$LB" -o /dev/null 2>/dev/null; then
    echo -e "${GREEN}LB ready after ${i}s${NC}"
    break
  fi
  if [ "$i" -eq "$MAX_RETRIES" ]; then
    echo -e "${RED}LB not ready after ${MAX_RETRIES}s${NC}"
    exit 1
  fi
  sleep 1
done

# ── Helper: login ────────────────────────────

login() {
  local user=$1 pass=$2 host=${3:-$LB}
  local resp
  resp=$(curl -sf "$host/api/v1/auth/login" \
    -H 'Content-Type: application/json' \
    -d "{\"login\":\"$user\",\"password\":\"$pass\"}")
  echo "$resp" | grep -o '"access_token":"[^"]*"' | head -1 | sed 's/.*"access_token":"\([^"]*\)".*/\1/'
}

authed() {
  # Usage: authed $TOKEN GET /api/v1/... [host]
  local token=$1 method=$2 path=$3 host=${4:-$LB}
  shift 3; shift 0 2>/dev/null || true
  curl -sf -X "$method" "$host$path" \
    -H "Authorization: Bearer $token" \
    -H 'Content-Type: application/json' \
    "$@"
}

# ── 1. Auth ──────────────────────────────────

echo -e "\n${YELLOW}1. Authentication${NC}"

ALICE_TOKEN=$(login alice password123)
if [ -n "$ALICE_TOKEN" ]; then ok "alice logged in"; else fail "alice login failed"; exit 1; fi

BOB_TOKEN=$(login bob password456)
if [ -n "$BOB_TOKEN" ]; then ok "bob logged in"; else fail "bob login failed"; exit 1; fi

ADMIN_TOKEN=$(login admin admin)
if [ -n "$ADMIN_TOKEN" ]; then ok "admin logged in"; else fail "admin login failed"; exit 1; fi

# ── 2. Install chat packages ────────────────

echo -e "\n${YELLOW}2. Install chat-core + chat packages${NC}"

# Check if chat-core is installed; if not, install via bundled packages or API
# (Packages may already be installed from bundled set)
PKGS=$(authed "$ADMIN_TOKEN" GET "/api/v1/packages" 2>/dev/null || echo "[]")
if echo "$PKGS" | grep -q '"chat-core"'; then
  ok "chat-core already installed"
else
  echo "  (chat-core not installed — bundled packages may need BUNDLED_PACKAGES config)"
  ok "chat-core check done (may need manual install)"
fi

# ── 3. Create conversation ───────────────────

echo -e "\n${YELLOW}3. Create conversation + send messages${NC}"

# Get alice's user ID
ALICE_ME=$(authed "$ALICE_TOKEN" GET "/api/v1/profile" 2>/dev/null || echo "{}")
ALICE_ID=$(echo "$ALICE_ME" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)

BOB_ME=$(authed "$BOB_TOKEN" GET "/api/v1/profile" 2>/dev/null || echo "{}")
BOB_ID=$(echo "$BOB_ME" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)

# Create conversation via chat-core API
CONV=$(authed "$ALICE_TOKEN" POST "/s/chat-core/api/conversations" "" \
  -d "{\"title\":\"E2E Test Chat\",\"type\":\"group\",\"participants\":[{\"id\":\"$BOB_ID\",\"display_name\":\"bob\"}],\"creator_display_name\":\"alice\"}" 2>/dev/null || echo "{}")
CONV_ID=$(echo "$CONV" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)

if [ -n "$CONV_ID" ]; then
  ok "conversation created: ${CONV_ID:0:8}..."
else
  fail "conversation creation failed"
  echo "  Response: $CONV"
fi

# ── 4. Send + read messages ──────────────────

echo -e "\n${YELLOW}4. Message send + read${NC}"

if [ -n "$CONV_ID" ]; then
  # Alice sends a message
  MSG1=$(authed "$ALICE_TOKEN" POST "/s/chat-core/api/messages/$CONV_ID" "" \
    -d '{"content":"Hello from alice!","content_type":"text"}' 2>/dev/null || echo "{}")
  MSG1_ID=$(echo "$MSG1" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)

  if [ -n "$MSG1_ID" ]; then ok "alice sent message"; else fail "alice send failed"; fi

  # Bob reads messages
  MSGS=$(authed "$BOB_TOKEN" GET "/s/chat-core/api/messages/$CONV_ID?limit=50" 2>/dev/null || echo "{}")
  if echo "$MSGS" | grep -q "Hello from alice"; then
    ok "bob received alice's message"
  else
    fail "bob did not receive message"
    echo "  Response: ${MSGS:0:200}"
  fi

  # Bob sends a reply
  MSG2=$(authed "$BOB_TOKEN" POST "/s/chat-core/api/messages/$CONV_ID" "" \
    -d '{"content":"Hello from bob!","content_type":"text"}' 2>/dev/null || echo "{}")
  MSG2_ID=$(echo "$MSG2" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)

  if [ -n "$MSG2_ID" ]; then ok "bob sent reply"; else fail "bob send failed"; fi
fi

# ── 5. Cross-replica consistency ─────────────

echo -e "\n${YELLOW}5. Cross-replica consistency${NC}"

if [ -n "$CONV_ID" ]; then
  # Login to each replica directly
  ALICE_R1=$(login alice password123 "$R1")
  BOB_R2=$(login bob password456 "$R2")

  # Alice sends via replica 1
  MSG3=$(curl -sf -X POST "$R1/s/chat-core/api/messages/$CONV_ID" \
    -H "Authorization: Bearer $ALICE_R1" \
    -H 'Content-Type: application/json' \
    -d '{"content":"Cross-replica test message","content_type":"text"}' 2>/dev/null || echo "{}")

  if echo "$MSG3" | grep -q '"id"'; then
    ok "alice sent via replica-1"
  else
    fail "alice send via replica-1 failed"
  fi

  # Small delay for pg replication
  sleep 1

  # Bob reads via replica 2
  MSGS_R2=$(curl -sf "$R2/s/chat-core/api/messages/$CONV_ID?limit=50" \
    -H "Authorization: Bearer $BOB_R2" 2>/dev/null || echo "{}")

  if echo "$MSGS_R2" | grep -q "Cross-replica test message"; then
    ok "bob sees cross-replica message via replica-2"
  else
    fail "cross-replica message not visible"
    echo "  Response: ${MSGS_R2:0:200}"
  fi
fi

# ── 6. Search ────────────────────────────────

echo -e "\n${YELLOW}6. Conversation search${NC}"

if [ -n "$CONV_ID" ]; then
  SEARCH=$(authed "$ALICE_TOKEN" GET "/s/chat-core/api/search?q=alice" 2>/dev/null || echo "{}")

  if echo "$SEARCH" | grep -q "Hello from alice"; then
    ok "search found message content"
  else
    fail "search did not find message"
    echo "  Response: ${SEARCH:0:200}"
  fi

  SEARCH_CONV=$(authed "$ALICE_TOKEN" GET "/s/chat-core/api/search?q=E2E%20Test" 2>/dev/null || echo "{}")
  if echo "$SEARCH_CONV" | grep -q "E2E Test Chat"; then
    ok "search found conversation by title"
  else
    fail "search did not find conversation by title"
  fi
fi

# ── 7. Message pagination ────────────────────

echo -e "\n${YELLOW}7. Message pagination${NC}"

if [ -n "$CONV_ID" ]; then
  # Send several more messages to test pagination
  for i in $(seq 1 5); do
    authed "$ALICE_TOKEN" POST "/s/chat-core/api/messages/$CONV_ID" "" \
      -d "{\"content\":\"Pagination test message $i\",\"content_type\":\"text\"}" >/dev/null 2>&1
  done

  # Fetch with limit=3
  PAGE1=$(authed "$ALICE_TOKEN" GET "/s/chat-core/api/messages/$CONV_ID?limit=3" 2>/dev/null || echo "{}")
  HAS_MORE=$(echo "$PAGE1" | grep -o '"has_more":true' || echo "")
  CURSOR=$(echo "$PAGE1" | grep -o '"next_cursor":"[^"]*"' | cut -d'"' -f4 || echo "")

  if [ -n "$HAS_MORE" ] && [ -n "$CURSOR" ]; then
    ok "pagination: first page has_more=true with cursor"

    # Fetch second page
    PAGE2=$(authed "$ALICE_TOKEN" GET "/s/chat-core/api/messages/$CONV_ID?limit=3&cursor=$CURSOR" 2>/dev/null || echo "{}")
    if echo "$PAGE2" | grep -q '"messages"'; then
      ok "pagination: second page returned messages"
    else
      fail "pagination: second page failed"
    fi
  else
    fail "pagination: expected has_more and cursor"
  fi
fi

# ── Summary ──────────────────────────────────

echo -e "\n════════════════════════════════════════"
echo -e "Results: ${GREEN}$pass passed${NC}, ${RED}$fail failed${NC}"
echo "════════════════════════════════════════"

[ "$fail" -eq 0 ] && exit 0 || exit 1
