#!/usr/bin/env bash
# ============================================================================
# tc-header.sh — fonctions partagées pour tous les scripts TC
# Source: source "$(dirname "$0")/tc-header.sh"
# ============================================================================
# Constants
URL="${URL:-https://localhost:31000}"
PASS="${PASS:-}"
WORLD="${WORLD:-Reve de Dragon}"
NAVIGATE="${1:-}"

PASSED=0; FAILED=0

die()    { echo "  ✖ $*"; exit 1; }
pass()   { echo "  ✔ $1"; PASSED=$((PASSED+1)); }
fail()   { echo "  ✘ $1"; FAILED=$((FAILED+1)); }

# Extract JSON value from evaluate_script output (```json\nVALUE\n```)
jse_get() {
	chrome-devtools evaluate_script "() => { $1 }" 2>/dev/null \
		| sed -n '/^```json$/{n;p;}'
}

jse_get_async() {
	chrome-devtools evaluate_script "async () => { $1 }" 2>/dev/null \
		| sed -n '/^```json$/{n;p;}'
}

# Async polling: single evaluate_script call, no bash loop
jse_wait_ready() {
	local timeout_s="${1:-60}" poll_ms="${2:-1000}"
	chrome-devtools evaluate_script "async () => {
		const limit = $timeout_s * 1000 / $poll_ms;
		for (let i = 0; i < limit; i++) {
			if (typeof game !== 'undefined' && game.ready) return 'ready';
			await new Promise(r => setTimeout(r, $poll_ms));
		}
		return 'timeout';
	}" 2>/dev/null | sed -n '/^```json$/{n;p;}' | tr -d '"\n'
}

# Navigate + login if needed (--navigate flag)
# Env: PASS (admin password), PASS_USER (user password, empty by default)
PASS_USER="${PASS_USER:-}"
tc_login() {
	[ -z "$PASS" ] && die "Admin password required: PASS=..."
	echo "→ Navigating to $URL ..."
	chrome-devtools new_page "$URL" --background false --timeout 15000 --isolatedContext "rdd-tests" >/dev/null 2>&1
	sleep 3
	local PW
	PW=$(jse_get "window.location.pathname" | tr -d '"\n')
	case "$PW" in
		*/join)
			chrome-devtools evaluate_script "() => {
				const sel = document.querySelector('select[name=userid]');
				if(sel) {
					const opts = Array.from(sel.options);
					const gm = opts.find(o => o.text === 'Gamemaster');
					const pick = gm || opts.find(o => o.value && !o.disabled) || opts.find(o => o.value);
					if(pick) sel.value = pick.value;
				}
				const admin = document.querySelector('input[name=adminPassword]');
				if(admin) admin.value = '$PASS';
				const btn = document.querySelector('button[name=join]');
				if(btn) btn.click();
			}" >/dev/null 2>&1 || true
			;;
		*/setup)
			chrome-devtools evaluate_script "() => {
				const links = document.querySelectorAll('[data-action=worldLaunch]');
				for(const l of links){
					const li = l.closest('li.package.world');
					if(li && li.querySelector('.package-title')?.textContent === '$WORLD'){ l.click(); break; }
				}
			}" >/dev/null 2>&1 || true
			;;
		*/auth)
			chrome-devtools evaluate_script "() => {
				const inp = document.querySelector('input[type=password]');
				if(inp) inp.value = '$PASS';
				const btn = document.querySelector('form button, button[type=submit]');
				if(btn) btn.click();
			}" >/dev/null 2>&1 || true
			;;
	esac
	echo "→ Waiting for game..."
	jse_wait_ready 60 2
}

# Ensure game is ready, login if --navigate
tc_ensure_ready() {
	local R
	R=$(jse_wait_ready 15 2)
	if [ "$R" != "ready" ] && [ "$NAVIGATE" = "--navigate" ]; then
		R=$(tc_login)
	fi
	[ "$R" != "ready" ] && die "Game not ready"
	echo "  ✓ Game ready"
	echo ""
}

# Assert helpers
assert_eq() { local t="$1" a="$2" e="$3"
	if [ "$a" = "$e" ]; then pass "$t"; else fail "$t (got '$a' expected '$e')"; fi
}
assert_gt() { local t="$1" a="$2" e="$3"
	if [ "$a" -gt "$e" ] 2>/dev/null; then pass "$t"; else fail "$t ($a <= $e)"; fi
}
assert_contains() { local t="$1" a="$2" e="$3"
	if echo "$a" | grep -q "$e"; then pass "$t"; else fail "$t (no '$e' in '$a')"; fi
}

# Extract field from JSON result
eval_ok() {
	local json="$1" k="$2"
	echo "$json" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$k',''))" 2>/dev/null
}

# Console error count
tc_console_errors() {
	chrome-devtools list_console_messages --types error 2>/dev/null | grep -c '^msgid=' || true
}

# Print summary
tc_summary() {
	local TOTAL=$((PASSED + FAILED))
	echo ""
	echo "╔══════════════════════════════════════════════════════════════╗"
	printf "║   %2d / %2d passed, %2d failed                              ║\n" "$PASSED" "$TOTAL" "$FAILED"
	echo "╚══════════════════════════════════════════════════════════════╝"
	echo ""
	[ "$FAILED" -gt 0 ] && exit 1 || exit 0
}