#!/usr/bin/env bash
# ============================================================================
# TC-08 — Système de Jet V1 (RdDRoll)
# Usage: ./tc-08-roll-v1.sh [--navigate]
#   Env: URL, PASS (admin password), PASS_USER (user password)
# ============================================================================
set -uo pipefail
source "$(dirname "$0")/tc-header.sh"

echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║   TC-08 — Système de Jet V1 (RdDRoll)                       ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""

tc_ensure_ready

# ============================================================================
# Setup: créer un acteur de test + items
# ============================================================================
SETUP=$(jse_get_async "
  const ex = game.actors.getName('TC-08 Test');
  if (ex) await ex.delete();
  const [actor] = await Actor.createDocuments([{
    type: 'personnage', name: 'TC-08 Test',
    system: {
      carac: { force: {value: 12}, intellect: {value: 10}, dexterite: {value: 11} },
      reve: {reve: {value: 12}, seui: {value: 12} },
      sante: { vie: {value: 12, max: 12}, endurance: {value: 20, max: 20} }
    }
  }]);
  if (!actor) return {error: 'create failed'};
  const [comp] = await actor.createEmbeddedDocuments('Item', [{
    type: 'competence', name: 'TC-08 Escrime',
    system: { categorie: 'melee', niveau: 5, xp: 0, base: 0, carac: 'force' }
  }]);
  const [compN] = await actor.createEmbeddedDocuments('Item', [{
    type: 'competence', name: 'TC-08 Natation',
    system: { categorie: 'physique', niveau: 3, xp: 0, base: 0, carac: 'force' }
  }]);
  const [arme] = await actor.createEmbeddedDocuments('Item', [{
    type: 'arme', name: 'TC-08 Epee',
    system: { categorie: 'cac', degats: '3', competence: 'TC-08 Escrime', competence2: '', encombrement: 2, mains: 1 }
  }]);
  const [sort] = await actor.createEmbeddedDocuments('Item', [{
    type: 'sort', name: 'TC-08 Lueur',
    system: { niveau: 4, voie: 'Oniros', draconic: 'Oniros', coutreve: 2, description: '' }
  }]);
  return { actorId: actor.id, compId: comp?.id, armeId: arme?.id, sortId: sort?.id };
")

ERR=$(eval_ok "$SETUP" error)
[ -z "$ERR" ] || [ "$ERR" = "None" ] || die "Setup: $ERR"

AID=$(eval_ok "$SETUP" actorId)
COMP_ID=$(eval_ok "$SETUP" compId)
ARME_ID=$(eval_ok "$SETUP" armeId)
SORT_ID=$(eval_ok "$SETUP" sortId)

# Helper: close all rdd-roll-dialogs
close_roll_dialogs() {
	jse_get_async "
		const apps = Object.values(ui.windows).filter(w => w.element?.classList?.contains('rdd-roll-dialog'));
		for (const a of apps) { a.rollData = a.rollData || {}; a.rollData.canClose = true; await a.close(); }
		return 'closed';
	" >/dev/null 2>&1
}

# ============================================================================
echo "--- TC-08-001: Jet Compétence — dialogue s'ouvre ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    await a.rollCompetence('$COMP_ID');
    await new Promise(r => setTimeout(r, 2000));
    const dlg = document.querySelector('.rdd-roll-dialog');
    const ok = !!dlg;
    return { opened: ok };
  } catch(e) { return {error: e?.message || String(e)}; }
")
OPENED=$(eval_ok "$R" opened)
ERR=$(eval_ok "$R" error)
[ "$OPENED" = "True" ] && pass "TC-08-001: dialog RdDRoll ouvert" || fail "TC-08-001: dialog KO ($ERR)"
close_roll_dialogs

# ============================================================================
echo "--- TC-08-002: Jet Compétence — modificateurs ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    const { RdDRoll } = await import('/systems/foundryvtt-reve-de-dragon/module/rdd-roll.js');
    const comp = a.items.get('$COMP_ID');
    const rollData = {
      carac: { force: a.system.carac.force },
      selectedCarac: a.system.carac.force,
      competence: comp,
      diffLibre: 10,
      ajustementForce: 5,
      forceDiceResult: -1
    };
    const content = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', rollData);
    const dialog = new RdDRoll(a, rollData, content, {classes:['rdd-roll-dialog'], width:650, height:'fit-content'}, {
      name: 'comp-test', label: 'Test Comp',
      callbacks: [{action: r => { r.rolled = {isSuccess: true, code: 'normale'}; }}]
    });
    await dialog.render(true);
    await new Promise(r => setTimeout(r, 800));
    const el = dialog.element;
    const hasDiff = !!el?.querySelector('[name=diffLibre]');
    const hasCarac = !!el?.querySelector('[name=carac]');
    dialog.rollData.canClose = true;
    await dialog.close();
    return { opened: !!el, hasDiff, hasCarac };
  } catch(e) { return {error: e?.message || String(e)}; }
")
HASDIFF=$(eval_ok "$R" hasDiff)
[ "$HASDIFF" = "True" ] && pass "TC-08-002: champ difficulté visible" || fail "TC-08-002: KO ($HASDIFF)"
close_roll_dialogs

# ============================================================================
echo "--- TC-08-004: Jet Attaque ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    const arme = a.items.get('$ARME_ID');
    if (!arme) return {error: 'no arme'};
    await a.rollArme(arme, 'competence');
    await new Promise(r => setTimeout(r, 2000));
    const dlg = document.querySelector('.rdd-roll-dialog');
    const ok = !!dlg;
    return { opened: ok };
  } catch(e) { return {error: e?.message || String(e)}; }
")
OPENED=$(eval_ok "$R" opened)
ERR=$(eval_ok "$R" error)
[ "$OPENED" = "True" ] && pass "TC-08-004: dialog attaque ouvert" || fail "TC-08-004: KO ($ERR)"
close_roll_dialogs

# ============================================================================
echo "--- TC-08-007: Jet Sort ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    const sort = a.items.get('$SORT_ID');
    if (!sort) return {error: 'no sort'};
    if (typeof a.rollSort === 'function') await a.rollSort(sort.id);
    else if (typeof a.rollSortReserve === 'function') await a.rollSortReserve(sort.id);
    await new Promise(r => setTimeout(r, 2000));
    const dlg = document.querySelector('.rdd-roll-dialog');
    const ok = !!dlg;
    return { opened: ok };
  } catch(e) { return {error: e?.message || String(e)}; }
")
OPENED=$(eval_ok "$R" opened)
ERR=$(eval_ok "$R" error)
[ "$OPENED" = "True" ] && pass "TC-08-007: dialog sort ouvert" || fail "TC-08-007: KO ($ERR)"
close_roll_dialogs

# ============================================================================
echo "--- TC-08-009: Jet Éthylisme ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    await a.jetEthylisme();
    await new Promise(r => setTimeout(r, 2000));
    // jetEthylisme opens RdDRollDialogEthylisme, not RdDRoll
    const dlg = document.querySelector('.rdd-roll-ethylisme, .dialog-ethylisme, [class*=ethylisme]');
    const ok = !!dlg;
    // Also check any new dialog
    const allDialogs = document.querySelectorAll('.application.dialog');
    return { opened: ok, dialogCount: allDialogs.length };
  } catch(e) { return {error: e?.message || String(e)}; }
")
OPENED=$(eval_ok "$R" opened)
ERR=$(eval_ok "$R" error)
[ "$OPENED" = "True" ] && pass "TC-08-009: dialog éthylisme ouvert" || fail "TC-08-009: KO ($ERR)"
close_roll_dialogs

# ============================================================================
echo "--- TC-08-011: Message de résultat chat ---"
# ============================================================================
R=$(jse_get_async "
  try {
    const a = game.actors.get('$AID');
    if (!a) return {error: 'no actor'};
    const { RdDRoll } = await import('/systems/foundryvtt-reve-de-dragon/module/rdd-roll.js');
    const comp = a.items.get('$COMP_ID');
    const rollData = {
      carac: { force: a.system.carac.force },
      selectedCarac: a.system.carac.force,
      competence: comp,
      diffLibre: 0,
      forceDiceResult: 50
    };
    const content = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', rollData);
    const dialog = new RdDRoll(a, rollData, content, {classes:['rdd-roll-dialog'], width:650, height:'fit-content'}, {
      name: 'comp-res', label: 'Test Result',
      callbacks: [{action: r => { r.rolled = {isSuccess: true, code: 'particuliere'}; }}]
    });
    await dialog.render(true);
    await new Promise(r => setTimeout(r, 600));
    const btn = dialog.element?.querySelector('button[data-action=onAction]');
    if (btn) btn.click();
    await new Promise(r => setTimeout(r, 2000));
    const msgs = game.messages.contents.slice(-2);
    const found = msgs.some(m => (m.content || '').length > 50);
    return { chatHasResult: found, msgCount: msgs.length };
  } catch(e) { return {error: e?.message || String(e)}; }
")
CHATOK=$(eval_ok "$R" chatHasResult)
ERR=$(eval_ok "$R" error)
[ "$CHATOK" = "True" ] && pass "TC-08-011: message chat résultat roll" || fail "TC-08-011: KO ($ERR)"
close_roll_dialogs

# ============================================================================
echo ""
echo "--- Cleanup ---"
CLEANUP=$(jse_get_async "
  const a = game.actors.getName('TC-08 Test');
  if (a) { await a.delete(); return 'deleted'; }
  return 'none';
" | tr -d '"\n')
[ "$CLEANUP" = "deleted" ] && pass "Cleanup: actor deleted" || fail "Cleanup: $CLEANUP"

echo ""
echo "--- Console errors ---"
ERRS=$(tc_console_errors)
[ "$ERRS" -le 5 ] 2>/dev/null && pass "Console errors ≤5 ($ERRS)" || fail "Console errors: $ERRS"

tc_summary