#!/usr/bin/env bash
# ============================================================================
# TC-05 — Acteur Véhicule
# Usage: ./tc-05-acteur-vehicule.sh [--navigate]
#   --navigate : force navigation + login
#   Env: URL, PASS (admin password)
#
# Atomic: tout polling interne (async + setTimeout Promise).
# ============================================================================
set -uo pipefail

URL="${URL:-https://localhost:31000}"
PASS="${PASS:-}"
NAVIGATE="${1:-}"

PASSED=0; FAILED=0

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

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

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'
}

# ============================================================================
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║   TC-05 — Acteur Véhicule                                  ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""

R=$(jse_wait_ready 15 2)
if [ "$R" != "ready" ] && [ "$NAVIGATE" = "--navigate" ]; then
	[ -z "$PASS" ] && die "Admin password required: PASS=..."
	echo "→ Navigating to $URL ..."
	chrome-devtools new_page "$URL" --background false --timeout 15000 --isolatedContext "rdd-tc05" >/dev/null 2>&1
	sleep 3
	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 === 'Reve de Dragon'){ 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..."
	R=$(jse_wait_ready 60 2)
fi

[ "$R" != "ready" ] && die "Game not ready"
echo "  ✓ Game ready"
echo ""

# ============================================================================
# TC-05-001: Vehicle creation + sheet
# ============================================================================
echo "--- TC-05-001: Véhicule creation + sheet ---"

RESULT=$(chrome-devtools evaluate_script "async () => {
  if (typeof game === 'undefined' || !game.ready) return {error: 'NOT_READY'};
  try {
    const existing = game.actors.getName('TC-05 Test Vehicule');
    if (existing) await existing.delete();

    const [actor] = await Actor.createDocuments([{type: 'vehicule', name: 'TC-05 Test Vehicule'}]);
    if (!actor) return {error: 'create failed'};

    const sheet = await actor.sheet.render(true);
    await new Promise(r => setTimeout(r, 800));
    const sheetName = sheet.constructor.name;
    await sheet.close();

    return {
      ok: true, actorId: actor.id, sheetName,
      items: actor.items.contents.length,
      classe: actor.constructor.name,
      isVehicule: typeof actor.isVehicule === 'function' ? actor.isVehicule() : false,
      resistance: actor.system.etat?.resistance?.value,
      resistanceMax: actor.system.etat?.resistance?.max,
      structure: actor.system.etat?.structure?.value,
      structureMax: actor.system.etat?.structure?.max
    };
  } catch(e) { return {error: e?.message || String(e)}; }
}" 2>/dev/null | sed -n '/^```json$/{n;p;}')

eval_ok() { echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }

[ -z "$(eval_ok error)" ] 2>/dev/null || [ "$(eval_ok error)" = "None" ] || die "TC-05-001: $(eval_ok error)"

SH_NAME=$(eval_ok sheetName)
CLS=$(eval_ok isVehicule)
RES=$(eval_ok resistance)
RMAX=$(eval_ok resistanceMax)
STR=$(eval_ok structure)
SMAX=$(eval_ok structureMax)
AID=$(eval_ok actorId)

[ "$SH_NAME" = "RdDActorVehiculeSheetV2" ] && pass "TC-05-001a: Sheet $SH_NAME" || fail "TC-05-001a: Expected RdDActorVehiculeSheetV2 got $SH_NAME"
[ "$CLS" = "True" ] && pass "TC-05-001b: isVehicule() true" || fail "TC-05-001b: isVehicule()=$CLS"
[ "$RES" = "20" ] && pass "TC-05-001c: resistance = $RES" || fail "TC-05-001c: resistance = $RES (expected 20)"
[ "$STR" = "10" ] && pass "TC-05-001d: structure = $STR" || fail "TC-05-001d: structure = $STR (expected 10)"

echo ""
echo "--- TC-05-002: Structure / Resistance update ---"

RESULT2=$(chrome-devtools evaluate_script "async () => {
  if (typeof game === 'undefined' || !game.ready) return {error: 'NOT_READY'};
  try {
    const actor = game.actors.get('$AID');
    if (!actor) return {error: 'Actor not found'};

    // Modify via direct update (vehicleIncDec is available)
    await actor.update({'system.etat.resistance.value': 15, 'system.etat.structure.value': 5});
    await new Promise(r => setTimeout(r, 300));

    const res = actor.system.etat.resistance.value;
    const str = actor.system.etat.structure.value;

    // Use vehicleIncDec
    await actor.vehicleIncDec('resistance', -3);
    await actor.vehicleIncDec('structure', 2);
    await new Promise(r => setTimeout(r, 300));

    return {
      ok: true,
      afterUpdate: {resistance: res, structure: str},
      afterIncDec: {resistance: actor.system.etat.resistance.value, structure: actor.system.etat.structure.value}
    };
  } catch(e) { return {error: e?.message || String(e)}; }
}" 2>/dev/null | sed -n '/^```json$/{n;p;}')

eval2() { echo "$RESULT2" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }

E2=$(eval2 error)
[ -z "$E2" ] || [ "$E2" = "None" ] || die "TC-05-002: $E2"

AU=$(eval2 afterUpdate)
AI=$(eval2 afterIncDec)

echo "$AU" | grep -q "'resistance': 15" && pass "TC-05-002a: resistance → 15 via update" || fail "TC-05-002a: resistance update failed ($AU)"
echo "$AU" | grep -q "'structure': 5" && pass "TC-05-002b: structure → 5 via update" || fail "TC-05-002b: structure update failed ($AU)"
echo "$AI" | grep -q "'resistance': 12" && pass "TC-05-002c: resistance → 12 via vehicleIncDec" || fail "TC-05-002c: resistance incdec failed ($AI)"
echo "$AI" | grep -q "'structure': 7" && pass "TC-05-002d: structure → 7 via vehicleIncDec" || fail "TC-05-002d: structure incdec failed ($AI)"

echo ""
echo "--- Cleanup ---"
CLEANUP=$(chrome-devtools evaluate_script "async () => {
  const actor = game.actors.getName('TC-05 Test Vehicule');
  if (actor) { await actor.delete(); return 'deleted'; }
  return 'none';
}" 2>/dev/null | sed -n '/^```json$/{n;p;}' | tr -d '"\n')
[ "$CLEANUP" = "deleted" ] && pass "Cleanup: actor deleted" || fail "Cleanup: $CLEANUP"

echo ""
echo "--- Console errors ---"
ERRS=$(chrome-devtools list_console_messages --types error 2>/dev/null | grep -c '^msgid=' || true)
[ "$ERRS" -le 2 ] 2>/dev/null && pass "Console errors ≤2 ($ERRS)" || fail "Console errors: $ERRS"

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