window.XiaobaiPageModules.register("ladder", ["ladderView"], { bind: bindLadderEvents });

function renderLadderMini(ladders) {
  const container = document.querySelector("#ladderMini");
  const highest = ladders.length ? Math.max(...ladders.map((item) => number(item.level))) : 0;
  setText("maxHeight", highest ? `最高 ${highest} 板` : "暂无");
  container.innerHTML = ladders.slice(0, 5).map((group) => {
    const allNames = group.stocks.map((stock) => stock.name).filter(Boolean);
    const visibleNames = allNames.slice(0, 3).join("、");
    const suffix = allNames.length > 3 ? ` <em>等 ${number(group.count)} 只</em>` : "";
    return `<div class="pool-side-group">
      <div><strong>${escapeHtml(group.label)}</strong><small>${number(group.count)} 只</small></div>
      <p title="${escapeHtml(allNames.join("、"))}">${escapeHtml(visibleNames || "--")}${suffix}</p>
    </div>`;
  }).join("") || emptyStateHtml("暂无梯队数据");
}

function renderSectorMini(sectors) {
  document.querySelector("#sectorMini").innerHTML = sectors.slice(0, 7).map((sector) => `
    <div class="pool-hot-row"><strong title="${escapeHtml(sector.name)}">${escapeHtml(sector.name)}</strong><span>${number(sector.count)}</span></div>
  `).join("") || emptyStateHtml("暂无板块数据");
}

function renderLadderBoard(ladders) {
  const container = document.querySelector("#ladderBoard");
  const insights = document.querySelector("#ladderInsights");
  const ordered = [...ladders].sort((left, right) => number(right.level) - number(left.level));
  const maxLevel = ordered.length ? Math.max(...ordered.map((group) => number(group.level))) : 0;
  const topVisibleLevel = Math.max(5, maxLevel);
  const groupMap = new Map(ordered.map((group) => [number(group.level), group]));
  const displayGroups = Array.from({ length: topVisibleLevel }, (_, index) => {
    const level = topVisibleLevel - index;
    return groupMap.get(level) || { level, label: level === 1 ? "首板" : level === 5 && maxLevel < 5 ? "5板+" : `${level}板`, count: 0, stocks: [] };
  });
  const total = ordered.reduce((sum, group) => sum + number(group.count), 0);
  const currentDate = displayCompactDate(state.dashboard?.meta?.trade_date || elements.tradeDate.value);
  const previousDate = displayCompactDate(state.dashboard?.meta?.previous_trade_date || "");
  setText("ladderDateRange", `数据日期 ${currentDate}`);
  container.innerHTML = displayGroups.map((group) => {
    const level = number(group.level);
    const limit = level === 1 || level === 2 ? 8 : 99;
    const expanded = state.expandedLadderLevels.has(level);
    const groupStocks = [...(group.stocks || [])].sort((left, right) => {
      if (state.ladderSortMode === "open") {
        return number(left.open_times) - number(right.open_times)
          || String(left.first_time || "99:99:99").localeCompare(String(right.first_time || "99:99:99"));
      }
      return String(left.first_time || "99:99:99").localeCompare(String(right.first_time || "99:99:99"));
    });
    const stocks = expanded ? groupStocks : groupStocks.slice(0, limit);
    const remaining = Math.max(0, groupStocks.length - stocks.length);
    const label = group.label || (level === 1 ? "首板" : level === 5 && maxLevel < 5 ? "5板+" : `${level}板`);
    const color = { 1: "#3370ff", 2: "#16a34a", 3: "#b45309", 4: "#e04536" }[level] || "#8f959e";
    return `
      <section class="market-ladder-tier ${number(group.count) ? "" : "is-gap"}" data-ladder-level-card="${level}">
        <div class="market-ladder-label" style="--tier-color:${color}"><div class="market-ladder-level"><span class="market-ladder-dot"></span>${escapeHtml(label)}</div><div class="market-ladder-count">${number(group.count)} 只</div>${number(group.count) && level > 1 ? `<div class="market-ladder-rate">${escapeHtml(label)} · <b>${formatNumber(number(group.count) / Math.max(number(groupMap.get(level - 1)?.count), 1) * 100, 1)}%</b></div>` : ""}</div>
        <div class="market-ladder-stocks">${stocks.length ? stocks.map((stock) => {
          const onePrice = String(stock.first_time || "").startsWith("09:25") && number(stock.open_times) === 0;
          const broken = number(stock.open_times) >= 6;
          const amount = number(stock.seal_amount_million) ? `封单 ${formatNumber(stock.seal_amount_million, 0)} 万` : `成交 ${formatNumber(stock.amount_billion, 1)} 亿`;
          return `<button type="button" class="market-ladder-stock" data-code="${escapeHtml(stock.code)}" aria-label="查看 ${escapeHtml(stock.name)} ${escapeHtml(stock.code)}详情">
            <span class="market-ladder-stock-first"><strong>${escapeHtml(stock.name)}</strong><small class="stock-code">${escapeHtml(stock.code)}</small><span class="market-ladder-tags">${onePrice ? '<em class="market-ladder-tag one-price">一字</em>' : ""}${broken ? `<em class="market-ladder-tag broken">烂板×${number(stock.open_times)}</em>` : ""}</span></span>
            <span class="market-ladder-stock-second"><b>${escapeHtml(stock.sector || stock.reason || "其他")}</b><small>${stock.first_time && stock.first_time !== "--" ? escapeHtml(stock.first_time) : "时间待校正"}</small><small>${amount}</small></span>
          </button>`;
        }).join("") : `<div class="market-ladder-gap-note">${level >= maxLevel ? `断层 · ${escapeHtml(label)}及以上空缺` : "该层暂时空缺"}</div>`}${groupStocks.length > limit ? `<button class="market-ladder-more" type="button" data-ladder-level="${level}">${expanded ? "收起" : `展开剩余 ${remaining} 只`}<i data-lucide="chevron-${expanded ? "up" : "down"}"></i></button>` : ""}</div>
      </section>`;
  }).join("");
  const structureRows = displayGroups.filter((group) => number(group.count) || number(group.level) <= maxLevel + 1);
  const maxCount = Math.max(1, ...structureRows.map((group) => number(group.count)));
  const rateRows = (state.dashboard?.limit_performance || []).map((row) => ({
    label: `${row.label || (number(row.level) === 1 ? "昨日首板" : `昨日${number(row.level)}板`)} → 今日`,
    value: clamp(number(row.advance_rate), 0, 100),
  }));
  const previousMax = Math.max(0, ...(state.dashboard?.yesterday_limits || []).map((row) => number(row.prior_streak)));
  const spaceChange = previousMax && maxLevel < previousMax ? `较昨日 ${previousMax} 板 ↓ 空间压缩` : previousMax && maxLevel > previousMax ? `较昨日 ${previousMax} 板 ↑ 高度抬升` : "高度与昨日接近";
  const spaceNote = maxLevel >= 5 ? "高位梯队仍有辨识度，重点观察承接而非单看高度。" : maxLevel >= 3 ? "空间位于中段，梯队延续性比绝对高度更重要。" : "高度受到压缩，先观察首板向二板的结构修复。";
  const strongestGroup = structureRows.reduce((best, group) => number(group.count) > number(best?.count) ? group : best, structureRows[0]);
  insights.innerHTML = `
    <section class="market-ladder-insight-card market-ladder-apex-card"><header><h3>空间板</h3><span>市场高度</span></header><div class="market-ladder-apex"><div><strong>${maxLevel ? `${maxLevel} 板` : "--"}</strong><em>${escapeHtml(spaceChange)}</em></div></div><p>${spaceNote}</p></section>
    <section class="market-ladder-insight-card"><header><h3>梯队结构</h3><span>完整度</span></header><div class="market-ladder-pyramid">${structureRows.map((group) => `<div class="market-ladder-pyramid-row ${number(group.count) ? "" : "is-gap"}"><span>${escapeHtml(group.label || `${number(group.level)}板`)}</span><i><b style="width:${Math.max(number(group.count) ? 8 : 100, number(group.count) / maxCount * 100)}%"></b></i><strong>${number(group.count) ? `${number(group.count)} 只` : "断层"}</strong></div>`).join("")}</div><p>断层越少，梯队从低位向高位传导越连贯。当前腰部为 <b>${escapeHtml(strongestGroup?.label || "--")}</b>。</p></section>
    <section class="market-ladder-insight-card"><header><h3>晋级率参考</h3><span>昨日梯队 → 今日</span></header><div class="market-ladder-rate-list">${rateRows.length ? rateRows.map((row) => `<div><span>${escapeHtml(row.label)}</span><i><b class="${row.value === 0 ? "is-zero" : row.value < 20 ? "is-low" : ""}" style="width:${Math.max(row.value, row.value > 0 ? 2 : 0)}%"></b></i><strong class="${row.value === 0 ? "is-zero" : row.value < 20 ? "is-low" : ""}">${formatNumber(row.value, 1)}%</strong></div>`).join("") : '<div class="empty-state">暂无可比梯队</div>'}</div><small class="market-ladder-source">数据来自“涨停表现”页 · 昨日梯队样本</small></section>`;
  container.querySelectorAll("[data-ladder-level]").forEach((button) => {
    button.addEventListener("click", () => {
      const level = number(button.dataset.ladderLevel);
      if (state.expandedLadderLevels.has(level)) state.expandedLadderLevels.delete(level);
      else state.expandedLadderLevels.add(level);
      renderLadderBoard(state.dashboard?.ladders || []);
    });
  });
  bindStockRows(container);
  refreshIcons();
}


function bindLadderEvents() {
  document.querySelectorAll("[data-ladder-sort]").forEach((button) => {
    button.addEventListener("click", () => {
      state.ladderSortMode = button.dataset.ladderSort === "open" ? "open" : "time";
      document.querySelectorAll("[data-ladder-sort]").forEach((item) => {
        const active = item === button;
        item.classList.toggle("active", active);
        item.setAttribute("aria-pressed", String(active));
      });
      renderLadderBoard(state.dashboard?.ladders || []);
    });
  });
  document.querySelector("#ladderExportButton").addEventListener("click", exportLadder);
}
