(() => {
  "use strict";

  const MODULE_PHASES = {
  "1": [
    {
      "title": "① 基础参数与设计暴雨",
      "description": "确定流域面积、暴雨分区、点雨量均值和面雨量折减参数，是后续洪水推求的共同基础。",
      "programIds": [
        "1-01"
      ]
    },
    {
      "title": "② 洪水推求方法",
      "description": "按铁一两所法、地区经验公式、瞬时单位线、推理公式和中小河流经验公式分别计算洪峰与过程。",
      "programIds": [
        "1-02",
        "1-03",
        "1-04",
        "1-05",
        "1-09"
      ]
    },
    {
      "title": "③ 参证站与频率分析",
      "description": "按参证站资料进行面积比拟、双对数内插和频率适线，可独立用于缺少暴雨资料时的洪峰复核。",
      "programIds": [
        "1-11",
        "1-12",
        "1-13"
      ]
    },
    {
      "title": "④ 过程线合成与成果对比",
      "description": "合成洪水过程线、计算水库控制洪峰洪量，并对多方法成果进行比选。",
      "programIds": [
        "1-06",
        "1-08",
        "1-10"
      ]
    },
    {
      "title": "⑤ 下游衔接",
      "description": "推荐将采用洪水成果传递至水面线、壅水、冲刷和涉河安全复核；已有外部流量时可直接手动录入水位模块计算。",
      "programIds": [
        "4-01"
      ]
    }
  ],
  "2": [
    {
      "title": "① 灌溉需水与渠首控制",
      "description": "确定灌水模数、引水流量、渠首水位和提水灌溉设计流量。",
      "programIds": [
        "2-01",
        "2-02",
        "2-03",
        "2-04"
      ]
    },
    {
      "title": "② 泵站压力管道与机电",
      "description": "复核压力管道、设计扬程、安装高程、功率效率和主变容量。",
      "programIds": [
        "2-05",
        "2-06",
        "2-07",
        "2-08",
        "2-09"
      ]
    },
    {
      "title": "③ 明渠输水能力",
      "description": "计算明渠过流、临界不冲不淤、临界水深和断面优化。",
      "programIds": [
        "3-01",
        "3-02",
        "3-03",
        "3-04",
        "3-05",
        "3-06",
        "3-07"
      ]
    },
    {
      "title": "④ 渠道损失复核",
      "description": "核算渠道渗漏损失并反馈末端供水能力。",
      "programIds": [
        "3-08"
      ]
    }
  ],
  "3": [
    {
      "title": "① 河道基础与治导",
      "description": "估算河道流量、治导线宽度，并衔接水面线成果。",
      "programIds": [
        "3-09",
        "3-10",
        "4-01"
      ]
    },
    {
      "title": "② 涉河阻水与壅水",
      "description": "计算阻水比、桥前壅水和上游回水影响范围。",
      "programIds": [
        "3-15",
        "3-16",
        "3-14"
      ]
    },
    {
      "title": "③ 冲刷与基础安全",
      "description": "复核一般冲刷、局部冲刷、净空和基础埋深安全。",
      "programIds": [
        "3-13",
        "3-17",
        "3-12"
      ]
    },
    {
      "title": "④ 堤防高程复核",
      "description": "依据设计洪水位和风浪超高复核堤顶高程。",
      "programIds": [
        "3-11"
      ]
    }
  ],
  "4": [
    {
      "title": "① 断面水位计算",
      "description": "用曼宁公式和断面资料求取水位流量关系。",
      "programIds": [
        "4-02"
      ]
    },
    {
      "title": "② 多断面水面线",
      "description": "按能量方程或标准步法推求沿程水面线。",
      "programIds": [
        "4-01",
        "4-03"
      ]
    }
  ],
  "5": [
    {
      "title": "① 洪水入库与调洪",
      "description": "将设计洪水成果接入水库调洪演算。",
      "programIds": [
        "5-01"
      ]
    },
    {
      "title": "② 库容与运行调节",
      "description": "估算淤积、库容和年运用调节成果。",
      "programIds": [
        "5-02",
        "5-03",
        "5-08"
      ]
    },
    {
      "title": "③ 坝顶与坝体安全",
      "description": "复核坝顶超高、坝体轮廓、护坡和帷幕深度。",
      "programIds": [
        "5-04",
        "5-05",
        "5-06",
        "5-07"
      ]
    },
    {
      "title": "④ 闸门启闭复核",
      "description": "核算平面闸门启闭力和启闭设备选择。",
      "programIds": [
        "5-09"
      ]
    }
  ],
  "6": [
    {
      "title": "① 水能与装机",
      "description": "计算水电站出力并进行装机容量比选。",
      "programIds": [
        "6-01",
        "6-02"
      ]
    },
    {
      "title": "② 压力管道尺寸",
      "description": "确定压力管道直径、壁厚、进口淹没和通气管尺寸。",
      "programIds": [
        "6-03",
        "6-04",
        "6-05"
      ]
    },
    {
      "title": "③ 水锤与水头损失",
      "description": "复核水锤压力和管道水头损失。",
      "programIds": [
        "6-06",
        "6-07"
      ]
    }
  ],
  "7": [
    {
      "title": "① 泄流建筑物",
      "description": "计算水闸、溢流堰和泄槽泄流能力。",
      "programIds": [
        "7-01",
        "7-02",
        "7-03"
      ]
    },
    {
      "title": "② 消能与陡坡",
      "description": "复核消力池、海漫和陡坡水力条件。",
      "programIds": [
        "7-04",
        "7-05"
      ]
    },
    {
      "title": "③ 过水建筑物",
      "description": "计算渡槽、倒虹吸和桥孔水力。",
      "programIds": [
        "7-07",
        "7-08",
        "7-09"
      ]
    }
  ]
};

  function $(selector) { return document.querySelector(selector); }
  function escapeHtml(value) {
    return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
  }
  function api() { return window.pywebview && window.pywebview.api; }
  function isFloodModule(moduleKey) { return String(moduleKey) === "1"; }
  function brief(program) {
    const outputs = Array.isArray(program.outputs) ? program.outputs.slice(0, 4).join(" · ") : "";
    return outputs || "输入参数、计算成果表和计算书导出。";
  }
  function fallbackWorkbench(moduleKey) {
    const configs = window.PROGRAM_FORM_CONFIGS || {};
    const programs = Object.values(configs)
      .filter((cfg) => cfg.moduleKey === moduleKey)
      .map((cfg) => ({
        program_id: cfg.programId,
        name: cfg.title,
        outputs: String(cfg.description || "").split(" · ").filter(Boolean),
        statusKind: "ready",
        statusLabel: "可算",
        statusMessage: "依赖状态需在软件内读取",
        href: `${String(cfg.programId).toLowerCase()}.html`,
      }));
    return {
      ok: true,
      module: {
        key: moduleKey,
        name: document.body.dataset.moduleName || "模块工作台",
        description: document.body.dataset.moduleDesc || "按专业类别独立列出全部计算程序。",
        program_count: programs.length,
        status_done: programs.length,
        completed_count: 0,
        ready_count: programs.length,
        blocked_count: 0,
        color: "#0a5382",
      },
      programs,
    };
  }
  async function loadWorkbench(moduleKey) {
    if (api() && typeof api().get_module_workbench === "function") {
      try {
        const payload = await api().get_module_workbench(moduleKey);
        if (payload && payload.ok) return payload;
      } catch (error) {
        console.warn("module workbench bridge failed", error);
      }
    }
    return fallbackWorkbench(moduleKey);
  }
  function renderHero(module) {
    document.title = `${module.name} - 慧通智达水文计算云平台`;
    $(".module-title").textContent = module.name;
    $(".module-desc").textContent = module.description || "按专业类别独立列出全部计算程序。";
    $(".stats").innerHTML = `
      <span class="stat">已接入 <b class="mono">${escapeHtml(module.status_done ?? module.program_count ?? 0)}</b> / 总数 <b class="mono">${escapeHtml(module.program_count ?? 0)}</b></span>
      <span class="stat">已完成 <b class="mono">${escapeHtml(module.completed_count ?? 0)}</b></span>
      <span class="stat">可算 <b class="mono">${escapeHtml(module.ready_count ?? 0)}</b></span>
      <span class="stat">待算 <b class="mono">${escapeHtml(module.blocked_count ?? 0)}</b></span>`;
    document.documentElement.style.setProperty("--module-color", module.color || "#0a5382");
  }
  function getRegionOptions() {
    if (typeof window.getHydrologyRegionOptions === "function") return window.getHydrologyRegionOptions();
    return [{ code: "GS", name: "甘肃省", type: "省", statusKind: "configured" }];
  }
  function getSelectedRegion() {
    const code = typeof window.getSelectedHydrologyRegionCode === "function"
      ? window.getSelectedHydrologyRegionCode()
      : "GS";
    if (typeof window.getHydrologyRegionConfig === "function") return window.getHydrologyRegionConfig(code);
    return { code: "GS", name: "甘肃省", statusKind: "configured", statusLabel: "甘肃资料体系已启用", canCalculate: true };
  }
  function renderRegionDetail(region) {
    const methodGroups = (region.methodGroups || []).map((group) => `
      <article class="region-method">
        <strong>${escapeHtml(group.title)}</strong>
        <span>${(group.methods || []).map(escapeHtml).join("、")}</span>
      </article>
    `).join("");
    const atlasItems = (region.atlasSources || []).map((source) => `<li>${escapeHtml(source)}</li>`).join("");
    const paramItems = (region.parameterGroups || []).map((item) => `<li>${escapeHtml(item)}</li>`).join("");
    const notices = (region.notices || []).map((item) => `<p>${escapeHtml(item)}</p>`).join("");
    return `
      <div class="region-summary">
        <div>
          <b>${escapeHtml(region.name)}水文计算体系</b>
          <span>${escapeHtml(region.statusLabel || "")}</span>
        </div>
        <em>${region.canCalculate ? "可进入计算" : "需先接入本省资料"}</em>
      </div>
      <div class="region-grid">
        <section><h3>图集与资料来源</h3><ul>${atlasItems}</ul></section>
        <section><h3>适用方法</h3><div class="region-methods">${methodGroups}</div></section>
        <section><h3>关键参数组</h3><ul>${paramItems}</ul></section>
      </div>
      <div class="region-notices">${notices}</div>
    `;
  }
  function renderRegionScopedStats(module, programs) {
    const stats = $(".stats");
    if (!stats) return;
    if (!isFloodModule(module.key)) {
      renderHero(module);
      return;
    }
    const region = getSelectedRegion();
    if (region.canCalculate) {
      stats.innerHTML = `
        <span class="stat">已接入 <b class="mono">${escapeHtml(module.status_done ?? module.program_count ?? 0)}</b> / 总数 <b class="mono">${escapeHtml(module.program_count ?? 0)}</b></span>
        <span class="stat">已完成 <b class="mono">${escapeHtml(module.completed_count ?? 0)}</b></span>
        <span class="stat">可算 <b class="mono">${escapeHtml(module.ready_count ?? 0)}</b></span>
        <span class="stat">待算 <b class="mono">${escapeHtml(module.blocked_count ?? 0)}</b></span>`;
      return;
    }
    const total = (programs || []).length;
    stats.innerHTML = `
      <span class="stat">本地区已接入 <b class="mono">0</b> / 总数 <b class="mono">${escapeHtml(total)}</b></span>
      <span class="stat">已完成 <b class="mono">0</b></span>
      <span class="stat">可算 <b class="mono">0</b></span>
      <span class="stat">待接入 <b class="mono">${escapeHtml(total)}</b></span>`;
  }
  function decorateProgramsForRegion(moduleKey, programs) {
    if (!isFloodModule(moduleKey)) return programs;
    const region = getSelectedRegion();
    if (region.canCalculate) return programs;
    return programs.map((program) => ({
      ...program,
      statusKind: "blocked",
      statusLabel: "待接入",
      statusMessage: `${region.name}水文图集、公式和参数库尚未接入，不能套用其他省份资料。`,
      href: "",
    }));
  }
  function renderRegionPanel(module, programs) {
    if (!isFloodModule(module.key)) return;
    const panel = document.querySelector("[data-hydrology-region-panel]");
    const select = $("#hydrology-region-select");
    const status = document.querySelector("[data-region-status]");
    const detail = document.querySelector("[data-region-detail]");
    if (!panel || !select || !status || !detail) return;

    const options = getRegionOptions();
    const selected = getSelectedRegion();
    select.innerHTML = options.map((option) => {
      const suffix = option.statusKind === "configured" ? " · 已配置" : " · 待接入";
      return `<option value="${escapeHtml(option.code)}"${option.code === selected.code ? " selected" : ""}>${escapeHtml(option.name + suffix)}</option>`;
    }).join("");
    status.textContent = selected.statusLabel || "";
    status.className = `region-status is-${escapeHtml(selected.statusKind || "pending")}`;
    detail.innerHTML = renderRegionDetail(selected);
    select.onchange = () => {
      if (typeof window.setSelectedHydrologyRegionCode === "function") {
        window.setSelectedHydrologyRegionCode(select.value);
      }
      const refreshed = getSelectedRegion();
      status.textContent = refreshed.statusLabel || "";
      status.className = `region-status is-${escapeHtml(refreshed.statusKind || "pending")}`;
      detail.innerHTML = renderRegionDetail(refreshed);
      renderRegionScopedStats(module, programs || []);
      renderCatalog(decorateProgramsForRegion(module.key, programs || []));
    };
    renderRegionScopedStats(module, programs || []);
  }
  function renderProgram(program) {
    const id = program.program_id || program.programId;
    const statusKind = program.statusKind || "ready";
    const isBlocked = statusKind === "blocked";
    const tag = isBlocked ? "div" : "a";
    const href = isBlocked ? "" : ` href="${escapeHtml(program.href || `${String(id).toLowerCase()}.html`)}"`;
    const need = isBlocked ? `<span class="need">${escapeHtml(program.statusMessage || "需先完成上游程序")}</span>` : "";
    return `<${tag} class="program is-${escapeHtml(statusKind)}"${href}>
      <span class="pid">${escapeHtml(id)}</span>
      <span><strong>${escapeHtml(program.name)}</strong><span class="brief">${escapeHtml(brief(program))}</span>${need}</span>
      <span class="status">${escapeHtml(program.statusLabel || "可算")}</span>
    </${tag}>`;
  }
  function renderCatalog(programs) {
    const ordered = [...programs].sort((left, right) => String(left.program_id || left.programId).localeCompare(String(right.program_id || right.programId), "zh-Hans-CN", { numeric: true }));
    $(".flow").innerHTML = ordered.length
      ? `<div class="program-grid program-catalog">${ordered.map(renderProgram).join("")}</div>`
      : '<div class="empty">本模块暂无程序清单。</div>';
  }
  document.addEventListener("DOMContentLoaded", async () => {
    const moduleKey = window.MODULE_HOME_KEY;
    const payload = await loadWorkbench(moduleKey);
    renderHero(payload.module);
    renderRegionPanel(payload.module, payload.programs || []);
    renderCatalog(decorateProgramsForRegion(payload.module.key, payload.programs || []));
  });
})();
