// ---- 03_npc_ui_quests.js ----
// guardian_system source chunk
// Original lines: 2960-3429



// ====== UI ======

function _gUi(key, withArgs) {
  return _rmTranslate(`lwj.guardian.${key}`, withArgs);
}

function _gClassRaw(classeOrId) {
  const id = typeof classeOrId === "string" ? classeOrId : classeOrId?.id;
  if (id === CG.classes.warrior) return _gUi("class.warrior");
  if (id === CG.classes.archer) return _gUi("class.archer");
  if (id === CG.classes.mage) return _gUi("class.mage");
  return _rmText(String(id ?? ""));
}

function _gBtn(form, player, text, icon) {
  try {
    if (uiSimple(player) || !icon) return form.button(text);
    return form.button(text, icon);
  } catch (e) {
    try { return form.button(text); } catch (e2) {}
  }
}
function _gHeader(form, text) { try { return form.header(text); } catch (e) {} return form; }
function _gDivider(form) { try { return form.divider(); } catch (e) {} return form; }
function _gLabel(form, text) { try { return form.label(text); } catch (e) {} return form; }

function _localizationKeyForTypeId(typeId) {
  try {
    const it = new ItemStack(typeId, 1);
    const key = it?.localizationKey ?? it?.type?.localizationKey;
    return (typeof key === "string" && key.length > 0) ? key : "";
  } catch (e) {}
  return "";
}
function _itemNameRawByLocalizationKey(typeId) {
  const key = _localizationKeyForTypeId(typeId);
  return key ? _rmTranslate(key) : null;
}

function _gSend(player, ...parts) {
  try { __LWJ_MUTE_MESSAGE__(player, _rmJoin(...parts)); } catch (e) {}
}

function isTieredArmorQuestClass(classId) {
  return classId === CG.classes.warrior || classId === CG.classes.archer;
}

function getTieredQuestCompletedKey(classId) {
  return classId === CG.classes.archer ? "quest_archer_completed_all" : "quest_warrior_completed_all";
}

function getTieredQuestCompletedDescKey(classId) {
  return classId === CG.classes.archer ? "quest_archer_completed_all_desc" : "quest_warrior_completed_all_desc";
}


function menuPreClasse(player, npc) {
  const guardian = npc ?? findGuardianNpcAny();
  const opcoes = [];
  const apprentice = isApprentice(player);

  if (!apprentice) {
    opcoes.push({
      text: _gUi("btn_become_apprentice"),
      icon: "textures/lorewarden/ui/guardian_book",
      run: () => {
        ensureApprentice(player);
        _gSend(player, _gUi("msg.apprentice_started"));
        system.run(() => openNpcUI(player, guardian));
      }
    });
  } else {
    opcoes.push({
      text: _gUi("btn_choose_apprentice_class"),
      icon: "textures/lorewarden/ui/guardian_classes",
      run: () => escolherClasseParaDesbloqueio(player, guardian)
    });
  }

  if (isCreative(player)) {
    opcoes.push({
      text: _gUi("btn_unlock_creative"),
      icon: "textures/lorewarden/ui/guardian_creative",
      run: () => escolherClasseCriativo(player, guardian)
    });
  }

  opcoes.push({
    text: isGuardianFollowing(player, guardian) ? _gUi("btn_stop_following") : _gUi("btn_follow_me"),
    icon: "textures/lorewarden/ui/guardian_follow",
    run: () => {
      toggleGuardianFollow(player, guardian);
      system.run(() => openNpcUI(player, guardian));
    }
  });

  opcoes.push({ text: _gUi("btn_close"), icon: "textures/lorewarden/ui/guardian_close", run: () => {} });

  const body = apprentice ? _gUi("npc_body_apprentice") : _gUi("npc_body_no_class_new");
  const form = new ActionFormData()
    .title(_gUi("npc_title"))
    .body(body);
  _gHeader(form, _gUi("npc_title"));
  _gDivider(form);

  for (const o of opcoes) _gBtn(form, player, o.text, o.icon);

  _showFormSafe(form, player).then((res) => {
    if (res.canceled) return;
    try { opcoes[res.selection]?.run?.(); } catch (e) {}
  });
}

function escolherClasseParaDesbloqueio(player, npc) {
  const form = new ActionFormData()
    .title(_gUi("unlock_title"))
    .body(_gUi("unlock_body_apprentice"));
  _gHeader(form, _gUi("unlock_title"));
  _gDivider(form);

  _gBtn(form, player, _gUi("class.warrior"), "textures/lorewarden/ui/guardian_warrior");
  _gBtn(form, player, _gUi("class.archer"), "textures/lorewarden/ui/guardian_archer");
  _gBtn(form, player, _gUi("class.mage"), "textures/lorewarden/ui/guardian_mage");
  _gBtn(form, player, _gUi("common.back"), "textures/lorewarden/ui/guardian_back");

  _showFormSafe(form, player).then((res) => {
    if (res.canceled) return;
    if (res.selection === 3) return openNpcUI(player, npc);

    const classe = CLASSES[res.selection];
    system.run(() => {
      try { ensureApprentice(player); desbloquearClasse(player, classe, "main"); } catch (e) {}
    });
  });
}

function escolherClasseCriativo(player, npc) {
  if (!isCreative(player)) {
    _gSend(player, _gUi("creative_only"));
    return;
  }

  const form = new ActionFormData()
    .title(_gUi("creative_unlock_title"))
    .body(_gUi("creative_unlock_body"));
  _gHeader(form, _gUi("creative_unlock_title"));
  _gDivider(form);

  _gBtn(form, player, _gUi("class.warrior"), "textures/lorewarden/ui/guardian_warrior");
  _gBtn(form, player, _gUi("class.archer"), "textures/lorewarden/ui/guardian_archer");
  _gBtn(form, player, _gUi("class.mage"), "textures/lorewarden/ui/guardian_mage");
  _gBtn(form, player, _gUi("common.back"), "textures/lorewarden/ui/guardian_back");

  _showFormSafe(form, player).then((res) => {
    if (res.canceled) return;
    if (res.selection === 3) return openNpcUI(player, npc);

    const classe = CLASSES[res.selection];
    system.run(() => {
      try { desbloquearClasseCriativo(player, classe); } catch (e) {}
    });
  });
}

function desbloquearClasseCriativo(player, classe) {
  if (!isCreative(player)) {
    _gSend(player, _gUi("creative_only"));
    return;
  }

  setClasse(player, classe);

  // Para manter consistência com o caminho principal (e evitar estados estranhos)
  try { player.addTag(TAG_CAMINHO_PRINCIPAL); } catch (e) {}
  // Creative assignment mirrors the main class rewards, but automatic status-effect bonuses stay disabled.
  try { giveUnlockXP_MainOnly(player); } catch (e) {}
  try { giveMainArmor(player, classe.id); } catch (e) {}
  try { giveKit(player, classe.id); } catch (e) {}
  try { giveManualBook(player, classe.id); } catch (e) {}
  // (v0.0.7) Efeitos infinitos agora são desbloqueados por troca no Suporte de Poções.
  // try { void grantClasseRewardEffects(player, classe.id); } catch (e) {}

  _gSend(player, _gUi("msg.class_unlocked_creative_prefix"), _gClassRaw(classe));
}

function getQuestClassIcon(classe) {
  if (!classe?.id) return "textures/lorewarden/ui/guardian_book";
  if (classe.id === CG.classes.warrior) return "textures/lorewarden/ui/guardian_warrior";
  if (classe.id === CG.classes.archer) return "textures/lorewarden/ui/guardian_archer";
  if (classe.id === CG.classes.mage) return "textures/lorewarden/ui/guardian_mage";
  return "textures/lorewarden/ui/guardian_book";
}


function getQuestItemLabel(player, itemId) {
  return String(itemId ?? "unknown");
}

function getQuestItemLabelRaw(itemId) {
  if (itemId !== "ANY_PLANK" && itemId !== "ANY_LOG") {
    const localized = _itemNameRawByLocalizationKey(itemId);
    if (localized) return localized;
  }
  const map = {
    "minecraft:iron_ingot": _gUi("item.iron_ingot"),
    "minecraft:iron_chestplate": _gUi("item.iron_chestplate"),
    "minecraft:iron_leggings": _gUi("item.iron_leggings"),
    "minecraft:iron_boots": _gUi("item.iron_boots"),
    "minecraft:bone": _gUi("item.bone"),
    "minecraft:glass_bottle": _gUi("item.glass_bottle"),
    "minecraft:gold_ingot": _gUi("item.gold_ingot"),
    "minecraft:gold_nugget": _gUi("item.gold_nugget"),
    "minecraft:diamond": _gUi("item.diamond"),
    "minecraft:apple": _gUi("item.apple"),
    "minecraft:wheat": _gUi("item.wheat"),
    "minecraft:stick": _gUi("item.stick"),
    "minecraft:leather": _gUi("item.leather"),
    "minecraft:flint": _gUi("item.flint"),
    "minecraft:feather": _gUi("item.feather"),
    "minecraft:string": _gUi("item.string"),
    "minecraft:cobblestone": _gUi("item.cobblestone"),
    "minecraft:redstone": _gUi("item.redstone"),
    "minecraft:lapis_lazuli": _gUi("item.lapis_lazuli"),
    "ANY_PLANK": _gUi("item.any_plank"),
    "ANY_LOG": _gUi("item.any_log"),
  };
  return map[itemId] ?? _gUi("item.unknown");
}

function getQuestState(player, classe) {
  if (!classe?.id) return null;

  const state = {
    classId: classe.id,
    icon: getQuestClassIcon(classe),
    title: "",
    desc: "",
    pathName: "",
    objective: "",
    reward: "",
    status: "",
    stepsSummary: "",
    current: 0,
    required: 0,
    canTurnIn: false,
    completedAll: false,
    repeatable: false,
    step: 0,
    totalSteps: 0,
    rewardItem: undefined,
    tagToUnlock: "",
    itemReq: undefined,
    qty: 0,
  };

  if (classe.id === CG.classes.warrior) {
    const reqs = [0, 8, 7, 4];
    const rewards = [null, "minecraft:iron_chestplate", "minecraft:iron_leggings", "minecraft:iron_boots"];
    const done1 = player.hasTag(CG.questTags.warriorDone[0]);
    const done2 = player.hasTag(CG.questTags.warriorDone[1]);
    const done3 = player.hasTag(CG.questTags.warriorDone[2]);

    state.pathName = _gUi("quest.path_warrior");
    state.totalSteps = 3;

    if (done3) {
      state.title = _gUi("quest_warrior_completed_all");
      state.desc = _gUi("quest_warrior_completed_all_desc");
      state.status = _gUi("quest.status_completed");
      state.completedAll = true;
      state.step = 3;
    } else {
      if (done2) state.step = 3;
      else if (done1) state.step = 2;
      else state.step = 1;

      state.title = _gUi(`quest_warrior_step${state.step}_name`);
      state.desc = _gUi(`quest_warrior_step${state.step}_desc`);
      state.itemReq = "minecraft:iron_ingot";
      state.qty = reqs[state.step];
      state.required = state.qty;
      state.current = Math.min(countItems(player, state.itemReq), state.required);
      state.rewardItem = rewards[state.step];
      state.reward = getQuestItemLabelRaw(state.rewardItem);
      state.objective = _rmJoin(_gUi("quest.objective_deliver_prefix"), _rmText(`${state.required}x `), getQuestItemLabelRaw(state.itemReq), _gUi("quest.objective_deliver_suffix"));
      state.canTurnIn = countItems(player, state.itemReq) >= state.required;
      state.status = state.canTurnIn ? _gUi("quest.status_ready") : _gUi("quest.status_in_progress");
      state.tagToUnlock = cgWarriorQuestTag(state.step);
    }

    const nextStep = done3 ? 4 : (done2 ? 3 : (done1 ? 2 : 1));
    const rows = [
      [1, _gUi("quest_warrior_step1_name"), _rmJoin("8x ", getQuestItemLabelRaw("minecraft:iron_ingot"), " → ", getQuestItemLabelRaw("minecraft:iron_chestplate"))],
      [2, _gUi("quest_warrior_step2_name"), _rmJoin("7x ", getQuestItemLabelRaw("minecraft:iron_ingot"), " → ", getQuestItemLabelRaw("minecraft:iron_leggings"))],
      [3, _gUi("quest_warrior_step3_name"), _rmJoin("4x ", getQuestItemLabelRaw("minecraft:iron_ingot"), " → ", getQuestItemLabelRaw("minecraft:iron_boots"))],
    ];
    const stepParts = [];
    for (const [idx, name, extra] of rows) {
      const mark = idx < nextStep ? "§a✓" : (idx === nextStep ? "§e➜" : "§7•");
      if (stepParts.length) stepParts.push("\n");
      stepParts.push(mark, " ", name, "\n§7   ", extra);
    }
    state.stepsSummary = _rmJoin(...stepParts);

    return state;
  }

  if (classe.id === CG.classes.archer) {
    const reqs = [0, 8, 7, 4];
    const rewards = [null, "minecraft:leather_chestplate", "minecraft:leather_leggings", "minecraft:leather_boots"];
    const done1 = player.hasTag(CG.questTags.archerDone[0]);
    const done2 = player.hasTag(CG.questTags.archerDone[1]);
    const done3 = player.hasTag(CG.questTags.archerDone[2]);

    state.pathName = _gUi("quest.path_archer");
    state.totalSteps = 3;

    if (done3) {
      state.title = _gUi("quest_archer_completed_all");
      state.desc = _gUi("quest_archer_completed_all_desc");
      state.status = _gUi("quest.status_completed");
      state.completedAll = true;
      state.step = 3;
    } else {
      if (done2) state.step = 3;
      else if (done1) state.step = 2;
      else state.step = 1;

      state.title = _gUi(`quest_archer_step${state.step}_name`);
      state.desc = _gUi(`quest_archer_step${state.step}_desc`);
      state.itemReq = "minecraft:leather";
      state.qty = reqs[state.step];
      state.required = state.qty;
      state.current = Math.min(countItems(player, state.itemReq), state.required);
      state.rewardItem = rewards[state.step];
      state.reward = getQuestItemLabelRaw(state.rewardItem);
      state.objective = _rmJoin(_gUi("quest.objective_deliver_prefix"), _rmText(`${state.required}x `), getQuestItemLabelRaw(state.itemReq), _gUi("quest.objective_deliver_suffix"));
      state.canTurnIn = countItems(player, state.itemReq) >= state.required;
      state.status = state.canTurnIn ? _gUi("quest.status_ready") : _gUi("quest.status_in_progress");
      state.tagToUnlock = cgArcherQuestTag(state.step);
    }

    const nextStep = done3 ? 4 : (done2 ? 3 : (done1 ? 2 : 1));
    const rows = [
      [1, _gUi("quest_archer_step1_name"), _rmJoin("8x ", getQuestItemLabelRaw("minecraft:leather"), " → ", getQuestItemLabelRaw("minecraft:leather_chestplate"))],
      [2, _gUi("quest_archer_step2_name"), _rmJoin("7x ", getQuestItemLabelRaw("minecraft:leather"), " → ", getQuestItemLabelRaw("minecraft:leather_leggings"))],
      [3, _gUi("quest_archer_step3_name"), _rmJoin("4x ", getQuestItemLabelRaw("minecraft:leather"), " → ", getQuestItemLabelRaw("minecraft:leather_boots"))],
    ];
    const stepParts = [];
    for (const [idx, name, extra] of rows) {
      const mark = idx < nextStep ? "§a✓" : (idx === nextStep ? "§e➜" : "§7•");
      if (stepParts.length) stepParts.push("\n");
      stepParts.push(mark, " ", name, "\n§7   ", extra);
    }
    state.stepsSummary = _rmJoin(...stepParts);

    return state;
  }

  if (classe.id === CG.classes.mage) {
    state.pathName = _gUi("quest.path_mage");
    state.title = _gUi("quest_mage_name");
    state.desc = _gUi("quest_mage_desc");
    state.itemReq = "minecraft:glass_bottle";
    state.qty = 16;
    state.required = state.qty;
    state.current = Math.min(countItems(player, state.itemReq), state.required);
    state.objective = _rmJoin(_gUi("quest.objective_deliver_prefix"), _rmText(`${state.required}x `), getQuestItemLabelRaw(state.itemReq), _gUi("quest.objective_deliver_suffix"));
    state.reward = _gUi("quest.reward_level");
    state.repeatable = true;
    state.canTurnIn = countItems(player, state.itemReq) >= state.required;
    state.status = state.canTurnIn ? _gUi("quest.status_ready") : _gUi("quest.status_in_progress_repeatable");
    return state;
  }

  return state;
}


function buildQuestSummaryForPostClass(player, quest) {
  if (!quest) return _gUi("npc_body_has_class");

  const raw = _rmJoin(
    _gUi("npc_body_has_class"),
    "\n\n§l§6", _gUi("quest.active_label"), "§r\n§f", quest.title, "§r"
  );
  if (quest.desc) _rmPush(raw, "\n§7", quest.desc, "§r");
  _rmPush(raw, "\n", _gUi("quest.label_status"), ": ", quest.status);
  if (!quest.completedAll && quest.required > 0) {
    _rmPush(raw, "\n", _gUi("quest.label_progress"), ": §f", _rmText(`${quest.current}/${quest.required}`), "§r");
  }
  return raw;
}

function buildQuestDetailsBody(player, quest) {
  if (!quest) return _gUi("quest.not_found");

  const raw = _rmJoin("§l", quest.title, "§r");
  if (quest.desc) _rmPush(raw, "\n§7", quest.desc, "§r");
  if (quest.pathName || (!quest.completedAll && quest.step > 0 && quest.totalSteps > 0) || quest.status || quest.objective || quest.reward || quest.repeatable || quest.stepsSummary) {
    _rmPush(raw, "\n");
  }
  if (quest.pathName) _rmPush(raw, "\n§6", _gUi("quest.label_journey"), ": §r", quest.pathName);
  if (!quest.completedAll && quest.step > 0 && quest.totalSteps > 0) {
    _rmPush(raw, "\n§6", _gUi("quest.label_step"), ": §r", _rmText(`${quest.step}/${quest.totalSteps}`));
  }
  _rmPush(raw, "\n§6", _gUi("quest.label_status"), ": §r", quest.status);

  if (!quest.completedAll) {
    _rmPush(raw, "\n§6", _gUi("quest.label_objective"), ": §r", quest.objective);
    if (quest.required > 0) {
      _rmPush(raw, "\n§6", _gUi("quest.label_progress"), ": §r", _rmText(`${quest.current}/${quest.required}`));
    }
    if (quest.reward) {
      _rmPush(raw, "\n§6", _gUi("quest.label_reward"), ": §r", quest.reward);
    }
  }

  if (quest.repeatable) {
    _rmPush(raw, "\n§b", _gUi("quest.repeatable"), "§r");
  }

  if (quest.stepsSummary) {
    _rmPush(raw, "\n\n§l§6", _gUi("quest.journey_steps"), "§r\n", quest.stepsSummary);
  }

  return raw;
}

async function tryCompleteCurrentQuest(player, classe, quest) {

  if (!classe?.id || !quest) return false;

  if (isTieredArmorQuestClass(classe.id)) {
    if (quest.completedAll) {
      __LWJ_MUTE_MESSAGE__(player, _gUi(getTieredQuestCompletedKey(classe.id)));
      return false;
    }
    if (!quest.canTurnIn) {
      __LWJ_MUTE_MESSAGE__(player, _gUi("quest.not_finished"));
      return false;
    }

    removeItems(player, quest.itemReq, quest.required);
    giveArmorRewardItem(player, quest.rewardItem);
    player.addTag(quest.tagToUnlock);
    _gSend(player, "§a", _gUi("quest.step_complete_prefix"), " ", getQuestItemLabelRaw(quest.rewardItem));
    return true;
  }

  if (!quest.canTurnIn) {
    __LWJ_MUTE_MESSAGE__(player, _gUi("quest.not_finished"));
    return false;
  }

  removeItems(player, quest.itemReq, quest.required);
  awardExactQuestLevel(player, 1);
  __LWJ_MUTE_MESSAGE__(player, _gUi("quest.completed_msg"));
  return true;
}


async function tryCompleteCurrentQuestCreative(player, classe, quest) {
  if (!isCreative(player) || !classe?.id || !quest) return false;

  if (isTieredArmorQuestClass(classe.id)) {
    if (quest.completedAll) {
      __LWJ_MUTE_MESSAGE__(player, _gUi(getTieredQuestCompletedKey(classe.id)));
      return false;
    }

    giveArmorRewardItem(player, quest.rewardItem);
    player.addTag(quest.tagToUnlock);
    _gSend(player, "§b", _gUi("quest.creative_reward_prefix"), " ", getQuestItemLabelRaw(quest.rewardItem));
    return true;
  }

  awardExactQuestLevel(player, 1);
  __LWJ_MUTE_MESSAGE__(player, _gUi("quest.creative_reward_level_only"));
  return true;
}

function menuPosClasse(player, classe, npc) {

  const guardian = npc ?? findGuardianNpcAny();
  const quest = getQuestState(player, classe);
  const opcoes = [];
  const questHint = !quest
    ? []
    : (quest.completedAll
      ? ["\n", _gUi("quest_hint_completed")]
      : quest.canTurnIn
        ? ["\n", _gUi("quest_hint_ready")]
        : (quest.required > 0 ? [`\n§7${quest.current}/${quest.required}`] : []));

  opcoes.push({
    text: _rmJoin(_gUi("btn_quests"), questHint),
    icon: "textures/lorewarden/ui/guardian_book",
    run: () => abrirMenuMissoes(player, classe, guardian)
  });

  if (!hasFixedClass(player)) {
    opcoes.push({
      text: _gUi("btn_fix_current_class"),
      icon: "textures/lorewarden/ui/guardian_book",
      run: () => {
        _showFormSafe(new MessageFormData()
          .title(_gUi("fix_class_title"))
          .body(_rmJoin(_gUi("fix_class_body_prefix"), " ", _gClassRaw(classe), ".\n\n", _gUi("fix_class_body_suffix")))
          .button1(_gUi("fix_class_confirm"))
          .button2(_gUi("common.back")), player)
          .then((r) => {
            if (r?.canceled) return;
            if (r.selection === 0) {
              if (fixCurrentClass(player)) {
                _gSend(player, _gUi("msg.class_fixed_prefix"), " ", _gClassRaw(classe), "! ", _gUi("msg.class_fixed_suffix"));
              }
              system.run(() => openNpcUI(player, guardian));
            }
          });
      }
    });

    opcoes.push({
      text: _gUi("btn_switch_class"),
      icon: "textures/lorewarden/ui/guardian_classes",
      run: () => escolherClasseParaDesbloqueio(player, guardian)
    });
  }

  opcoes.push({
    text: isGuardianFollowing(player, guardian) ? _gUi("btn_stop_following") : _gUi("btn_follow_me"),
    icon: "textures/lorewarden/ui/guardian_follow",
    run: () => {
      toggleGuardianFollow(player, guardian);
      system.run(() => openNpcUI(player, guardian));
    }
  });

  if (isCreative(player)) {
    opcoes.push({
      text: _gUi("reset_title"),
      icon: "textures/lorewarden/ui/guardian_reset",
      run: () => {
        _showFormSafe(new MessageFormData()
          .title(_gUi("reset_title"))
          .body(_gUi("reset_body"))
          .button1(_gUi("reset_yes"))
          .button2(_gUi("reset_no")), player)
          .then((r) => {
            if (r.canceled) return;
            if (r.selection === 0) {
              resetClasse(player);
              _gSend(player, _gUi("reset_done"));
              openNpcUI(player, guardian);
            }
          });
      }
    });
  }

  opcoes.push({ text: _gUi("btn_close"), icon: "textures/lorewarden/ui/guardian_close", run: () => {} });

  const form = new ActionFormData()
    .title(_rmJoin("👤 ", _rmText(`${classe.emoji} `), _gClassRaw(classe)))
    .body(_rmJoin(
      hasFixedClass(player) ? _gUi("status_fixed") : _gUi("status_unfixed"),
      "\n",
      hasFixedClass(player) ? _gUi("status_fixed_detail") : _gUi("status_unfixed_detail"),
      "\n\n",
      buildQuestSummaryForPostClass(player, quest).rawtext
    ));

  for (const o of opcoes) {
    _gBtn(form, player, o.text, o.icon);
  }

  _showFormSafe(form, player).then((res) => {
    if (res.canceled) return;
    try { opcoes[res.selection]?.run?.(); } catch (e) {}
  });
}

function abrirMenuMissoes(player, classe, npc) {
  const quest = getQuestState(player, classe);
  const allowCreativeSkip = !!quest && !quest.completedAll && isCreative(player);

  const form = new ActionFormData()
    .title(_rmJoin(_gUi("quest_title_prefix"), " ", _gClassRaw(classe)))
    .body(buildQuestDetailsBody(player, quest));

  const primaryText = !quest
    ? _gUi("quest_primary_check")
    : (quest.completedAll
      ? _gUi("quest_primary_completed")
      : quest.canTurnIn
        ? _gUi("quest_primary_turn_in")
        : _gUi("quest_primary_track"));
  _gBtn(form, player, primaryText, quest?.icon ?? "textures/lorewarden/ui/guardian_book");
  if (allowCreativeSkip) {
    _gBtn(form, player, _gUi("quest_creative_skip"), "textures/lorewarden/ui/guardian_book");
  }
  _gBtn(form, player, _gUi("quest_back_guardian"), "textures/lorewarden/ui/guardian_back");

  _showFormSafe(form, player).then((res) => {
    if (res.canceled) return openNpcUI(player, npc);
    if (res.selection === undefined || res.selection === null) return openNpcUI(player, npc);

    const backIndex = allowCreativeSkip ? 2 : 1;
    if (res.selection === backIndex) return openNpcUI(player, npc);

    if (allowCreativeSkip && res.selection === 1) {
      Promise.resolve(tryCompleteCurrentQuestCreative(player, classe, quest)).then(() => system.run(() => abrirMenuMissoes(player, classe, npc)));
      return;
    }

    if (quest?.completedAll) {
      _gSend(player, _gUi(getTieredQuestCompletedDescKey(classe?.id)));
      return system.run(() => abrirMenuMissoes(player, classe, npc));
    }

    Promise.resolve(tryCompleteCurrentQuest(player, classe, quest)).then(() => system.run(() => abrirMenuMissoes(player, classe, npc)));
    return;
  });
}

function openNpcUI(player, npc) {
  const guardian = npc ?? findGuardianNpcAny();
  // Cache do NPC para evitar falhas de resolução (menus/follow)
  if (guardian && _isEntityValid(guardian)) { _gdcNpcCache = guardian; }
  const classe = getClasseInfo(player);
  if (!classe) menuPreClasse(player, guardian);
  else menuPosClasse(player, classe, guardian);
}

