// 干部管理系统 — PC 管理后台应用
// 依赖 shared.jsx 暴露的 window.Icon / Avatar / Badge / CADRES / DEPARTMENTS / LEVELS / getStats / parseResume
(function () {
  "use strict";
  const { useState, useMemo, useEffect, useRef } = React;
  const Icon = window.Icon;
  const Avatar = window.Avatar;
  const Badge = window.Badge;
  const DEPARTMENTS = window.DEPARTMENTS;
  const LEVELS = window.LEVELS;
  const parseResume = window.parseResume;

  // ===== 主应用（路由 + 花名册状态由这里统一管理） =====
  function App() {
    const [cadres, setCadres] = useState(window.CADRES);
    const [page, setPage] = useState("workbench"); // workbench | roster | detail | edit | import | assess | promotion | reward | talent | board | settings
    const [activeId, setActiveId] = useState(cadres[0].id);
    const [editId, setEditId] = useState(null);

    const goDetail = (id) => { setActiveId(id); setPage("detail"); };
    const goEdit = (id) => { setEditId(id); setPage("edit"); };
    const goImport = () => setPage("import");
    const goRoster = () => setPage("roster");

    const saveCadre = (id, patch) => {
      setCadres((prev) => prev.map((c) => (c.id === id ? { ...c, ...patch } : c)));
      setActiveId(id);
      setPage("detail");
    };

    const active = cadres.find((c) => c.id === activeId) || cadres[0];
    // detail/edit/import 属于花名册流程，侧边栏高亮「花名册管理」
    const activeNav = (page === "detail" || page === "edit" || page === "import") ? "roster" : page;

    const M = window.PC_MODULES;

    return (
      <React.Fragment>
        <Sidebar activeNav={activeNav} onNavigate={(p) => { setPage(p); }} />
        <div className="main">
          <Topbar page={page} active={active} onBack={goRoster} />
          <div className="content scroll-area">
            <div className="fade" key={page + activeId}>
              {page === "workbench" && <WorkbenchPage cadres={cadres} onOpen={goDetail} onNavigate={(p) => setPage(p)} onImport={goImport} />}
              {page === "roster" && <RosterPage cadres={cadres} onOpen={goDetail} onImport={goImport} />}
              {page === "detail" && <DetailPage cadre={active} onEdit={() => goEdit(active.id)} onBack={goRoster} />}
              {page === "edit" && <EditPage cadre={cadres.find((c) => c.id === editId) || active} onSave={saveCadre} onCancel={() => goDetail(editId)} />}
              {page === "import" && <ImportPage />}
              {page === "assess" && <M.AssessPage cadres={cadres} onOpen={goDetail} />}
              {page === "promotion" && <M.PromotionPage cadres={cadres} onOpen={goDetail} />}
              {page === "reward" && <M.RewardPage cadres={cadres} onOpen={goDetail} />}
              {page === "talent" && <M.TalentPage cadres={cadres} onOpen={goDetail} />}
              {page === "board" && <M.BoardPage cadres={cadres} onOpen={goDetail} />}
              {page === "settings" && <M.SettingsPage />}
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }

  // ===== 侧边栏 =====
  const NAV = [
    { id: "workbench",  icon: "dashboard",  label: "工作台" },
    { id: "roster",     icon: "roster",     label: "花名册管理" },
    { id: "assess",     icon: "assessment", label: "考核管理" },
    { id: "promotion",  icon: "trendUp",    label: "晋升管理" },
    { id: "reward",     icon: "award",      label: "奖惩记录" },
    { id: "talent",     icon: "grid",       label: "人才九宫格" },
    { id: "board",      icon: "chart",      label: "数据看板" },
    { id: "settings",   icon: "settings",   label: "系统设置" },
  ];
  function Sidebar({ activeNav, onNavigate }) {
    return (
      <aside className="sidebar">
        <div className="brand">
          <div className="bt">干部管理系统</div>
        </div>
        <nav className="nav-group scroll-area">
          {NAV.map((it, idx) => (
            <React.Fragment key={it.id}>
              {idx === 1 && <div className="nav-label">业务管理</div>}
              {idx === 6 && <div className="nav-label">数据与系统</div>}
              <button className={"nav-item" + (activeNav === it.id ? " active" : "")} onClick={() => onNavigate(it.id)}>
                <Icon name={it.icon} />
                <span>{it.label}</span>
              </button>
            </React.Fragment>
          ))}
        </nav>
        <div className="foot">
          <div className="av">林</div>
          <div>
            <div className="fn">林海峰</div>
            <div className="fr">组织部 · 部长</div>
          </div>
        </div>
      </aside>
    );
  }

  // ===== 顶栏 =====
  // 当前登录用户（与侧边栏底部一致）
  const ME = { name: "林海峰", pos: "组织部 · 部长", avatar: "林" };

  function Topbar({ page, active, onBack }) {
    const map = {
      workbench: ["工作台"],
      roster: ["花名册管理", "干部信息库"],
      detail: ["花名册管理", "干部信息库", active.name],
      edit: ["花名册管理", "干部信息库", "信息编辑"],
      import: ["花名册管理", "数据导入"],
      assess: ["考核管理"],
      promotion: ["晋升管理"],
      reward: ["奖惩记录"],
      talent: ["人才九宫格"],
      board: ["数据看板"],
      settings: ["系统设置"],
    };
    const crumb = map[page] || ["工作台"];
    const showBack = page !== "workbench" && page !== "roster";
    return (
      <header className="topbar">
        <img src="logo-yingjia.png" alt="赢加" className="topbar-logo" />
        {showBack && (
          <button className="icon-btn" onClick={onBack} title="返回"><Icon name="back" /></button>
        )}
        <div className="crumb">
          {crumb.map((c, i) => (
            <React.Fragment key={i}>
              {i > 0 && <span className="sep">/</span>}
              <span className={i === crumb.length - 1 ? "cur" : ""}>{c}</span>
            </React.Fragment>
          ))}
        </div>
        <div className="spacer"></div>
        <div className="search-box">
          <Icon name="search" />
          <input placeholder="搜索姓名 / 编号 / 部门" />
        </div>
        <button className="icon-btn" title="通知"><Icon name="bell" /><span className="dot"></span></button>
        <div className="user-chip" title={ME.name + " · " + ME.pos}>
          <div className="uc-av">{ME.avatar}</div>
          <div className="uc-info">
            <div className="uc-name">{ME.name}</div>
            <div className="uc-pos">{ME.pos}</div>
          </div>
          <Icon name="chevronDown" size={15} className="chev" />
        </div>
      </header>
    );
  }

  // ============ 工作台 ============
  function WorkbenchPage({ cadres, onOpen, onNavigate, onImport }) {
    const stats = useMemo(() => window.getStats(cadres), [cadres]);

    // 核心指标
    const pendingAssess = 8;   // 本月待考核人数（与考核管理对齐）
    const pendingPromo = 3;    // 晋升审批中件数（与晋升管理对齐）
    const todoCount = 3;       // 待办事项项数

    // 快捷操作
    const actions = [
      { icon: "plus", label: "新增干部", desc: "单条建档", tone: "r", on: () => onNavigate("roster") },
      { icon: "upload", label: "批量导入", desc: "Excel / OCR", tone: "b", on: () => onImport() },
      { icon: "assessment", label: "发起考核", desc: "新建周期", tone: "g", on: () => onNavigate("assess") },
      { icon: "sync", label: "同步朗新", desc: "一键拉取", tone: "y", on: () => onImport() },
    ];

    // 最近查看花名册（前 5 人）
    const recent = cadres.slice(0, 5);
    const recentTimes = ["10 分钟前", "1 小时前", "昨天 16:08", "2 天前", "上周三"];

    // 人才九宫格 - 简版统计
    const band = (s) => (s >= 4 ? "h" : s === 3 ? "m" : "l");
    const zones = [
      { key: "l-h", label: "潜力股", tone: "blue" },
      { key: "m-h", label: "明日之星", tone: "gold" },
      { key: "h-h", label: "明星", tone: "red" },
      { key: "l-m", label: "待发展", tone: "gray" },
      { key: "m-m", label: "中坚力量", tone: "blue" },
      { key: "h-m", label: "业绩骨干", tone: "green" },
      { key: "l-l", label: "需关注", tone: "orange" },
      { key: "m-l", label: "稳定贡献", tone: "gray" },
      { key: "h-l", label: "老黄牛", tone: "green" },
    ];
    const zoneCounts = {};
    cadres.forEach((c) => {
      const k = band(c.performance) + "-" + band(c.potential);
      zoneCounts[k] = (zoneCounts[k] || 0) + 1;
    });

    const toneBg = { r: "var(--red-light)", b: "var(--blue-light)", g: "#DCFCE7", y: "var(--gold-light)" };
    const toneFg = { r: "var(--red)", b: "var(--blue)", g: "var(--success)", y: "var(--gold)" };

    return (
      <div>
        <div className="page-head">
          <div>
            <div className="page-title"><span className="accent"></span>工作台</div>
            <div className="page-sub">您好，林部长 · 今天是 2026 年 6 月 29 日，您有 {todoCount} 项待办</div>
          </div>
        </div>

        {/* 核心指标 */}
        <div className="stat-grid">
          <div className="stat"><div className="ic r"><Icon name="users" /></div><div className="lbl">在册干部数</div><div className="val">{stats.total}<small>人</small></div><div className="delta">较上月 <b style={{ color: "var(--success)" }}>+2</b></div></div>
          <div className="stat"><div className="ic o"><Icon name="clock" /></div><div className="lbl">本月待考核</div><div className="val" style={{ color: "var(--warning)" }}>{pendingAssess}<small>人</small></div><div className="delta">截止 <b>07-15</b> · 已完成 {stats.total - pendingAssess} 人</div></div>
          <div className="stat"><div className="ic b"><Icon name="trendUp" /></div><div className="lbl">晋升审批中</div><div className="val">{pendingPromo}<small>件</small></div><div className="delta">公示 <b>1</b> · 推荐 / 考察 <b>2</b></div></div>
          <div className="stat"><div className="ic g"><Icon name="bell" /></div><div className="lbl">待办事项</div><div className="val">{todoCount}<small>项</small></div><div className="delta">本周新增 <b>2</b> 项</div></div>
        </div>

        {/* 快捷操作 + 系统状态 */}
        <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 18, marginBottom: 18, alignItems: "stretch" }}>
          {/* 快捷操作 */}
          <div className="card" style={{ padding: 18 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 14 }}>
              <Icon name="grid" />
              <h3 style={{ fontSize: 15, fontWeight: 600 }}>快捷操作</h3>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 12 }}>
              {actions.map((a) => (
                <button key={a.label} onClick={a.on} className="quick-btn" style={{ display: "flex", alignItems: "center", gap: 12, padding: "13px 16px", border: "1px solid var(--border-soft)", borderRadius: 10, cursor: "pointer", background: "var(--surface)", fontFamily: "inherit", transition: "all .15s", textAlign: "left" }}>
                  <div style={{ width: 40, height: 40, borderRadius: 10, background: toneBg[a.tone], color: toneFg[a.tone], display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}><Icon name={a.icon} size={20} /></div>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, color: "var(--text1)" }}>{a.label}</div>
                    <div style={{ fontSize: 11.5, color: "var(--text3)" }}>{a.desc}</div>
                  </div>
                </button>
              ))}
            </div>
          </div>

          {/* 系统状态 */}
          <div className="card sys-status" style={{ padding: 18 }}>
            <div className="ss-head">
              <Icon name="shield" />
              <h3 style={{ fontSize: 15, fontWeight: 600 }}>系统状态</h3>
              <span className="ss-all-dot good"></span>
              <span className="ss-all">全部正常</span>
            </div>
            <div className="ss-item">
              <span className="ss-dot good"></span>
              <div className="ss-main">
                <div className="ss-label">朗新数据同步</div>
                <div className="ss-value">已连接 · api.langxin.gov.cn</div>
              </div>
              <span className="ss-time">实时</span>
            </div>
            <div className="ss-item">
              <span className="ss-dot good"></span>
              <div className="ss-main">
                <div className="ss-label">上次同步时间</div>
                <div className="ss-value">2026-06-29 02:00 <span style={{ color: "var(--text3)", fontWeight: 400 }}>· 11 条变动</span></div>
              </div>
            </div>
            <div className="ss-item">
              <span className="ss-dot good"></span>
              <div className="ss-main">
                <div className="ss-label">数据存储状态</div>
                <div className="ss-value">本地，AES-256 加密</div>
              </div>
            </div>
            <div className="ss-item">
              <span className="ss-dot good"></span>
              <div className="ss-main">
                <div className="ss-label">钉钉审批状态</div>
                <div className="ss-value">已对接 · 工作通知可达</div>
              </div>
              <span className="ss-time">在线</span>
            </div>
          </div>
        </div>

        {/* 花名册最近查看 + 九宫格数据看板 */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1.2fr", gap: 18, alignItems: "start" }}>
          {/* 花名册（最近查看） */}
          <div className="card" style={{ padding: 0 }}>
            <div style={{ display: "flex", alignItems: "center", padding: "14px 18px", borderBottom: "1px solid var(--border-soft)" }}>
              <Icon name="history" />
              <h3 style={{ fontSize: 15, fontWeight: 600, marginLeft: 8 }}>干部花名册</h3>
              <span style={{ fontSize: 12, color: "var(--text3)", marginLeft: 8 }}>最近查看</span>
              <div style={{ flex: 1 }}></div>
              <button className="btn btn-sm" onClick={() => onNavigate("roster")}>查看全部 <Icon name="chevronRight" size={13} /></button>
            </div>
            <div>
              {recent.map((c, i) => (
                <div key={c.id} onClick={() => onOpen(c.id)} style={{ display: "flex", alignItems: "center", gap: 12, padding: "11px 18px", borderBottom: i < recent.length - 1 ? "1px solid var(--border-soft)" : "none", cursor: "pointer", transition: "background .12s" }} className="recent-row">
                  <Avatar cadre={c} size={36} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600 }}>{c.name}<span style={{ fontSize: 11.5, color: "var(--text3)", fontWeight: 400, marginLeft: 6 }}>{c.id}</span></div>
                    <div style={{ fontSize: 12, color: "var(--text2)" }}>{c.dept} · {c.position}</div>
                  </div>
                  <span style={{ fontSize: 11.5, color: "var(--text3)", flexShrink: 0 }}>{recentTimes[i]}</span>
                  <Icon name="chevronRight" size={14} style={{ color: "var(--text3)" }} />
                </div>
              ))}
            </div>
          </div>

          {/* 人才九宫格数据看板 */}
          <div className="card" style={{ padding: 18 }}>
            <div style={{ display: "flex", alignItems: "center", marginBottom: 14 }}>
              <Icon name="grid" />
              <h3 style={{ fontSize: 15, fontWeight: 600, marginLeft: 8 }}>人才九宫格</h3>
              <span style={{ fontSize: 12, color: "var(--text3)", marginLeft: 8 }}>业绩 × 潜力</span>
              <div style={{ flex: 1 }}></div>
              <button className="btn btn-sm" onClick={() => onNavigate("talent")}>进入盘点 <Icon name="chevronRight" size={13} /></button>
            </div>
            <div className="mini-board">
              {zones.map((z) => (
                <div key={z.key} className={"mini-cell tone-" + z.tone} onClick={() => onNavigate("talent")}>
                  <div className="mini-num">{zoneCounts[z.key] || 0}</div>
                  <div className="mini-label">{z.label}</div>
                </div>
              ))}
            </div>
            <div className="board-axes">
              <span className="ba-x">业绩 →</span>
              <span className="ba-y">↑ 潜力</span>
            </div>
            <div className="alert info" style={{ marginTop: 12, marginBottom: 0, fontSize: 12 }}><Icon name="trendUp" />「明星」<b>{zoneCounts["h-h"] || 0}</b> 人为重点培养对象，「需关注」<b>{zoneCounts["l-l"] || 0}</b> 人需重点帮扶。</div>
          </div>
        </div>
      </div>
    );
  }

  // ============ P01 干部信息库列表 ============
  function RosterPage({ cadres, onOpen, onImport }) {
    const [q, setQ] = useState("");
    const [dept, setDept] = useState("全部");
    const [level, setLevel] = useState("全部");
    const [gender, setGender] = useState("全部");
    const [pageNo, setPageNo] = useState(1);
    const pageSize = 10;

    const filtered = useMemo(() => cadres.filter((c) => {
      if (q && !(c.name.includes(q) || c.id.includes(q) || c.dept.includes(q) || c.position.includes(q))) return false;
      if (dept !== "全部" && c.dept !== dept) return false;
      if (level !== "全部" && c.level !== level) return false;
      if (gender !== "全部" && c.gender !== gender) return false;
      return true;
    }), [cadres, q, dept, level, gender]);

    const stats = useMemo(() => window.getStats(cadres), [cadres]);
    const pages = Math.max(1, Math.ceil(filtered.length / pageSize));
    const pageItems = filtered.slice((pageNo - 1) * pageSize, pageNo * pageSize);
    useEffect(() => { setPageNo(1); }, [q, dept, level, gender]);

    return (
      <div>
        <div className="page-head">
          <div>
            <div className="page-title"><span className="accent"></span>干部信息库</div>
            <div className="page-sub">在册干部全息档案，支持多维度筛选与检索</div>
          </div>
          <div style={{display:"flex",gap:10}}>
            <button className="btn"><Icon name="download" />导出花名册</button>
            <button className="btn btn-primary" onClick={onImport}><Icon name="upload" />数据导入</button>
          </div>
        </div>

        <div className="stat-grid">
          <div className="stat">
            <div className="ic r"><Icon name="users" /></div>
            <div className="lbl">在册干部</div>
            <div className="val">{stats.total}<small>人</small></div>
            <div className="delta">较上月 <b style={{color:"var(--success)"}}>+2</b></div>
          </div>
          <div className="stat">
            <div className="ic b"><Icon name="flag" /></div>
            <div className="lbl">中共党员</div>
            <div className="val">{stats.party}<small>人 · 预备 {stats.probParty}</small></div>
            <div className="delta">占比 <b>{Math.round(stats.party / stats.total * 100)}%</b></div>
          </div>
          <div className="stat">
            <div className="ic g"><Icon name="book" /></div>
            <div className="lbl">研究生及以上</div>
            <div className="val">{stats.master}<small>人 · 博士 {stats.doctor}</small></div>
            <div className="delta">高学历占比 <b>{Math.round(stats.master / stats.total * 100)}%</b></div>
          </div>
          <div className="stat">
            <div className="ic o"><Icon name="user" /></div>
            <div className="lbl">平均年龄</div>
            <div className="val">{stats.avgAge}<small>岁</small></div>
            <div className="delta">男 {stats.male} / 女 {stats.female}</div>
          </div>
        </div>

        <div className="toolbar">
          <div className="search-box" style={{width:240}}>
            <Icon name="search" />
            <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="搜索姓名 / 编号 / 职务" />
          </div>
          <DropdownSelect icon="building" value={dept} options={["全部", ...DEPARTMENTS]} onChange={setDept} />
          <DropdownSelect icon="shield" value={level} options={["全部", ...LEVELS]} onChange={setLevel} />
          <div className="seg">
            {[["全部","全部"],["男","男"],["女","女"]].map(([k,v]) => (
              <button key={v} className={gender === v ? "active" : ""} onClick={() => setGender(v)}>{k}</button>
            ))}
          </div>
          <div className="spacer"></div>
          <div style={{fontSize:12.5,color:"var(--text2)"}}>共 <b style={{color:"var(--text1)"}}>{filtered.length}</b> 条</div>
        </div>

        <div className="table-wrap">
          <table className="data">
            <thead>
              <tr>
                <th>姓名 / 编号</th>
                <th>性别</th>
                <th>年龄</th>
                <th>所属部门</th>
                <th>职务</th>
                <th>职级</th>
                <th>政治面貌</th>
                <th>学历</th>
                <th>最近考核</th>
                <th style={{width:90}}>操作</th>
              </tr>
            </thead>
            <tbody>
              {pageItems.map((c) => {
                const lastA = c.assessment[0];
                return (
                  <tr key={c.id} onClick={() => onOpen(c.id)}>
                    <td>
                      <div className="name-cell">
                        <Avatar cadre={c} size={38} />
                        <div>
                          <div className="nm">{c.name}</div>
                          <div className="iid">{c.id}</div>
                        </div>
                      </div>
                    </td>
                    <td>{c.gender}</td>
                    <td>{c.age}岁</td>
                    <td>{c.dept}</td>
                    <td>{c.position}</td>
                    <td><Badge color="blue">{c.level}</Badge></td>
                    <td>{c.party === "中共党员" ? <Badge color="red">中共党员</Badge> : c.party === "中共预备党员" ? <Badge color="orange">预备党员</Badge> : <span style={{color:"var(--text2)"}}>群众</span>}</td>
                    <td>{c.edu.level.replace("研究生","研")}</td>
                    <td>{lastA ? <Badge color={lastA.result === "优秀" ? "green" : lastA.result === "基本称职" ? "orange" : "gray"}>{lastA.result}</Badge> : "—"}</td>
                    <td>
                      <div className="col-actions" onClick={(e) => e.stopPropagation()}>
                        <button className="mini-btn" title="查看" onClick={() => onOpen(c.id)}><Icon name="eye" /></button>
                        <button className="mini-btn" title="编辑" onClick={() => onOpen(c.id)}><Icon name="edit" /></button>
                        <button className="mini-btn" title="更多"><Icon name="more" /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {pageItems.length === 0 && (
                <tr><td colSpan={10}><div className="empty"><Icon name="search" /><div>未找到符合条件的干部</div></div></td></tr>
              )}
            </tbody>
          </table>
          <div className="pagination">
            <div className="info">第 {(pageNo - 1) * pageSize + 1} - {Math.min(pageNo * pageSize, filtered.length)} 条 / 共 {filtered.length} 条</div>
            <div className="pg-btns">
              <button disabled={pageNo === 1} onClick={() => setPageNo(pageNo - 1)}>‹</button>
              {Array.from({length: pages}).map((_, i) => (
                <button key={i} className={pageNo === i + 1 ? "active" : ""} onClick={() => setPageNo(i + 1)}>{i + 1}</button>
              ))}
              <button disabled={pageNo === pages} onClick={() => setPageNo(pageNo + 1)}>›</button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  function DropdownSelect({ icon, value, options, onChange }) {
    const [open, setOpen] = useState(false);
    const ref = useRef(null);
    useEffect(() => {
      const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
      document.addEventListener("mousedown", h);
      return () => document.removeEventListener("mousedown", h);
    }, []);
    return (
      <div className="select" ref={ref} onClick={() => setOpen(!open)} style={{position:"relative"}}>
        <Icon name={icon} />
        <span>{value}</span>
        <Icon name="chevronDown" size={14} />
        {open && (
          <div style={{position:"absolute",top:"calc(100% + 6px)",left:0,minWidth:"100%",background:"#fff",border:"1px solid var(--border)",borderRadius:8,boxShadow:"var(--shadow-lg)",zIndex:30,padding:5,maxHeight:280,overflowY:"auto"}}>
            {options.map((o) => (
              <div key={o} onClick={(e) => { e.stopPropagation(); onChange(o); setOpen(false); }} style={{padding:"7px 12px",fontSize:13,borderRadius:6,cursor:"pointer",background:o === value ? "var(--red-soft)" : "none",color:o === value ? "var(--red)" : "var(--text1)",fontWeight:o === value ? 600 : 400}}>{o}</div>
            ))}
          </div>
        )}
      </div>
    );
  }

  // ============ P02 干部详情 ============
  function DetailPage({ cadre, onEdit, onBack }) {
    const [tab, setTab] = useState("basic");
    const tabs = [
      ["basic", "基本信息"],
      ["resume", "工作履历"],
      ["edu", "学历学位"],
      ["family", "家庭关系"],
      ["assessment", "考核记录"],
      ["reward", "奖惩记录"],
    ];
    return (
      <div>
        <div className="page-head">
          <div>
            <div className="page-title"><span className="accent"></span>干部详情</div>
            <div className="page-sub">干部编号 {cadre.id} · 全景档案</div>
          </div>
          <div style={{display:"flex",gap:10}}>
            <button className="btn" onClick={onBack}><Icon name="back" />返回列表</button>
            <button className="btn btn-primary" onClick={onEdit}><Icon name="edit" />编辑信息</button>
          </div>
        </div>

        <div className="detail-head">
          <div className="big-av" style={{background: cadre.gender === "女" ? "linear-gradient(135deg,#005d30,#003d1f)" : "linear-gradient(135deg,#0A3B24,#176543)"}}>{cadre.avatar}</div>
          <div className="dh-info">
            <div className="dh-name">
              {cadre.name}
              {cadre.party === "中共党员" && <Badge color="red" solid>中共党员</Badge>}
              {cadre.party === "中共预备党员" && <Badge color="orange" solid>预备党员</Badge>}
            </div>
            <div className="dh-pos">{cadre.position} · {cadre.dept}</div>
            <div className="dh-meta">
              <span><Icon name="user" />{cadre.gender} · {cadre.age}岁 · {cadre.nation}</span>
              <span><Icon name="shield" />{cadre.level}</span>
              <span><Icon name="book" />{cadre.edu.level}</span>
              <span><Icon name="location" />籍贯 {cadre.native}</span>
              <span><Icon name="phone" />{cadre.phone}</span>
            </div>
          </div>
          <div className="dh-actions">
            <button className="btn btn-blue btn-sm"><Icon name="doc" />导出档案</button>
            <button className="btn btn-sm"><Icon name="history" />变更记录</button>
          </div>
        </div>

        <div className="score-grid">
          <div className="score">
            <div className="sl">最近年度考核</div>
            <div className="sv" style={{color: cadre.assessment[0]?.result === "优秀" ? "var(--red)" : "var(--text1)"}}>{cadre.assessment[0]?.result || "—"}</div>
            <div className="sb">2025 年度 · {cadre.assessment[0]?.rank || ""}</div>
          </div>
          <div className="score">
            <div className="sl">业绩表现</div>
            <div className="sv" style={{color:"var(--blue)"}}>{"★".repeat(cadre.performance)}<span style={{color:"var(--border)"}}>{"★".repeat(5 - cadre.performance)}</span></div>
            <div className="sb">综合评定</div>
          </div>
          <div className="score">
            <div className="sl">发展潜力</div>
            <div className="sv" style={{color:"var(--gold)"}}>{"★".repeat(cadre.potential)}<span style={{color:"var(--border)"}}>{"★".repeat(5 - cadre.potential)}</span></div>
            <div className="sb">九宫格坐标</div>
          </div>
        </div>

        <div className="tabs">
          {tabs.map(([k, label]) => (
            <button key={k} className={"tab" + (tab === k ? " active" : "")} onClick={() => setTab(k)}>{label}</button>
          ))}
        </div>

        {tab === "basic" && (
          <div className="info-block fade">
            <h4><Icon name="user" />基本信息</h4>
            <div className="dl">
              <Field k="姓名" v={cadre.name} />
              <Field k="性别" v={cadre.gender} />
              <Field k="出生年月" v={cadre.birth} />
              <Field k="民族" v={cadre.nation} />
              <Field k="籍贯" v={cadre.native} />
              <Field k="政治面貌" v={cadre.party} />
              <Field k="入党时间" v={cadre.partyDate} />
              <Field k="参加工作时间" v={cadre.workAge + " 年"} />
              <Field k="现任职务" v={cadre.position} />
              <Field k="职级" v={cadre.level} />
              <Field k="所属部门" v={cadre.dept} />
              <Field k="干部编号" v={cadre.id} />
              <Field k="联系电话" v={cadre.phone} />
              <Field k="电子邮箱" v={cadre.email} />
            </div>
          </div>
        )}

        {tab === "resume" && (
          <div className="info-block fade">
            <h4><Icon name="history" />工作履历</h4>
            <div className="timeline">
              {parseResume(cadre.resume).map((r, i, arr) => (
                <div key={i} className={"tl-item" + (i === arr.length - 1 ? " now" : "")}>
                  <div className="tl-date">{r.from} — {r.to}</div>
                  <div className="tl-desc">{r.desc}</div>
                </div>
              ))}
            </div>
          </div>
        )}

        {tab === "edu" && (
          <div className="info-block fade">
            <h4><Icon name="book" />学历学位</h4>
            <div className="dl">
              <Field k="学历" v={cadre.edu.level} />
              <Field k="学位" v={cadre.edu.degree} />
              <Field k="毕业院校" v={cadre.edu.school} />
              <Field k="所学专业" v={cadre.edu.major} />
            </div>
          </div>
        )}

        {tab === "family" && (
          <div className="info-block fade">
            <h4><Icon name="users" />家庭主要成员</h4>
            <div className="dl full">
              <Field k="家庭情况" v={cadre.family} />
            </div>
          </div>
        )}

        {tab === "assessment" && (
          <div className="info-block fade">
            <h4><Icon name="assessment" />年度考核记录</h4>
            {cadre.assessment.map((a, i) => (
              <div key={i} className="record">
                <div className="ri" style={{background: a.result === "优秀" ? "#DCFCE7" : a.result === "基本称职" ? "#FEF3C7" : "var(--bg)", color: a.result === "优秀" ? "var(--success)" : a.result === "基本称职" ? "var(--warning)" : "var(--text2)"}}><Icon name="assessment" /></div>
                <div className="rc">
                  <div className="rt">{a.year} 年度考核 · <span style={{color: a.result === "优秀" ? "var(--success)" : a.result === "基本称职" ? "var(--warning)" : "var(--text2)"}}>{a.result}</span></div>
                  <div className="rs">排名 {a.rank} · 考核组织：本单位组织部门</div>
                </div>
                <Icon name="chevronRight" style={{color:"var(--text3)"}} />
              </div>
            ))}
          </div>
        )}

        {tab === "reward" && (
          <div className="info-block fade">
            <h4><Icon name="award" />奖惩记录</h4>
            {cadre.rewards.length === 0 && cadre.punish.length === 0 && (
              <div className="empty"><Icon name="award" /><div>暂无奖惩记录</div></div>
            )}
            {cadre.rewards.map((r, i) => (
              <div key={"r"+i} className="record">
                <div className="ri" style={{background:"var(--gold-light)",color:"var(--gold)"}}><Icon name="award" /></div>
                <div className="rc">
                  <div className="rt">{r.title}</div>
                  <div className="rs">{r.date} · 颁授：{r.org} · {r.type}</div>
                </div>
                <Badge color="gold">奖励</Badge>
              </div>
            ))}
            {cadre.punish.map((p, i) => (
              <div key={"p"+i} className="record">
                <div className="ri" style={{background:"#FEE2E2",color:"var(--danger)"}}><Icon name="flag" /></div>
                <div className="rc">
                  <div className="rt">{p.title}</div>
                  <div className="rs">{p.date} · {p.org} · {p.type}</div>
                </div>
                <Badge color="red">惩戒</Badge>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  function Field({ k, v }) {
    return <div className="dl-item"><div className="k">{k}</div><div className="v">{v || "—"}</div></div>;
  }

  // ============ P03 信息编辑 ============
  function EditPage({ cadre, onSave, onCancel }) {
    const [form, setForm] = useState({ ...cadre });
    const set = (key, val) => setForm((f) => ({ ...f, [key]: val }));
    const setEdu = (key, val) => setForm((f) => ({ ...f, edu: { ...f.edu, [key]: val } }));

    return (
      <div>
        <div className="page-head">
          <div>
            <div className="page-title"><span className="accent"></span>编辑干部信息</div>
            <div className="page-sub">{form.name} · {form.id} · 带 <span style={{color:"var(--red)"}}>*</span> 为必填项</div>
          </div>
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="user" />基本信息<span className="line"></span></div>
          <div className="form-grid">
            <FormInput label="姓名" req value={form.name} onChange={(v) => set("name", v)} />
            <FormSelect label="性别" req value={form.gender} options={["男","女"]} onChange={(v) => set("gender", v)} />
            <FormInput label="出生年月" req value={form.birth} onChange={(v) => set("birth", v)} hint="格式：YYYY-MM" />
            <FormSelect label="民族" value={form.nation} options={["汉族","回族","满族","蒙古族","藏族","其他"]} onChange={(v) => set("nation", v)} />
            <FormInput label="籍贯" value={form.native} onChange={(v) => set("native", v)} />
            <FormSelect label="政治面貌" req value={form.party} options={["中共党员","中共预备党员","群众"]} onChange={(v) => set("party", v)} />
            <FormInput label="入党时间" value={form.partyDate} onChange={(v) => set("partyDate", v)} />
            <FormInput label="参加工作年限（年）" value={String(form.workAge)} onChange={(v) => set("workAge", Number(v) || 0)} />
          </div>
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="briefcase" />职务信息<span className="line"></span></div>
          <div className="form-grid">
            <FormSelect label="所属部门" req value={form.dept} options={DEPARTMENTS} onChange={(v) => set("dept", v)} />
            <FormInput label="现任职务" req value={form.position} onChange={(v) => set("position", v)} />
            <FormSelect label="职级" req value={form.level} options={LEVELS} onChange={(v) => set("level", v)} />
            <FormSelect label="状态" value={form.status} options={["在任","挂职","培训","借调","退休"]} onChange={(v) => set("status", v)} />
          </div>
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="book" />学历学位<span className="line"></span></div>
          <div className="form-grid">
            <FormSelect label="学历" req value={form.edu.level} options={["博士研究生","硕士研究生","大学本科","大学专科","其他"]} onChange={(v) => setEdu("level", v)} />
            <FormInput label="学位" value={form.edu.degree} onChange={(v) => setEdu("degree", v)} />
            <FormInput label="毕业院校" value={form.edu.school} onChange={(v) => setEdu("school", v)} />
            <FormInput label="所学专业" value={form.edu.major} onChange={(v) => setEdu("major", v)} />
          </div>
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="phone" />联系方式<span className="line"></span></div>
          <div className="form-grid">
            <FormInput label="联系电话" value={form.phone} onChange={(v) => set("phone", v)} />
            <FormInput label="电子邮箱" value={form.email} onChange={(v) => set("email", v)} />
          </div>
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="history" />工作履历<span className="line"></span></div>
          <FormTextarea label="履历详情" value={form.resume} onChange={(v) => set("resume", v)} hint="每行一条，格式：起始时间 — 结束时间  职务描述" />
        </div>

        <div className="form-section">
          <div className="fs-head"><Icon name="users" />家庭关系<span className="line"></span></div>
          <FormTextarea label="家庭主要成员" value={form.family} onChange={(v) => set("family", v)} />
        </div>

        <div className="form-foot">
          <div className="alert info" style={{flex:1}}><Icon name="shield" />修改将记录到干部变更档案，关键信息变动需经组织部审批。</div>
          <button className="btn" onClick={onCancel}>取消</button>
          <button className="btn btn-primary" onClick={() => onSave(form.id, form)}><Icon name="save" />保存</button>
        </div>
      </div>
    );
  }

  function FormInput({ label, value, onChange, req, hint }) {
    return (
      <div className="field">
        <label>{req && <span className="req">*</span>}{label}</label>
        <input value={value || ""} onChange={(e) => onChange(e.target.value)} />
        {hint && <div className="hint">{hint}</div>}
      </div>
    );
  }
  function FormSelect({ label, value, options, onChange, req }) {
    return (
      <div className="field">
        <label>{req && <span className="req">*</span>}{label}</label>
        <select value={value || ""} onChange={(e) => onChange(e.target.value)}>
          {options.map((o) => <option key={o} value={o}>{o}</option>)}
        </select>
      </div>
    );
  }
  function FormTextarea({ label, value, onChange, hint }) {
    return (
      <div className="field full">
        <label>{label}</label>
        <textarea value={value || ""} onChange={(e) => onChange(e.target.value)} />
        {hint && <div className="hint">{hint}</div>}
      </div>
    );
  }

  // ============ P04 数据导入 ============
  function ImportPage() {
    const [mode, setMode] = useState(null);   // langxin | excel | ocr
    const [step, setStep] = useState(1);       // 1..3 向导步骤
    const [progress, setProgress] = useState(0);
    const result = { newCount: 3, updateCount: 7, failCount: 1, total: 11 };

    // 进度模拟：朗新/OCR 的 step2 自动推进到 step3
    useEffect(() => {
      if (!mode || mode === "excel") return;
      if (step !== 2) return;
      setProgress(0);
      const t = setInterval(() => {
        setProgress((p) => {
          if (p >= 100) { clearInterval(t); setTimeout(() => setStep(3), 500); return 100; }
          return p + 10;
        });
      }, 200);
      return () => clearInterval(t);
    }, [mode, step]);

    const reset = () => { setMode(null); setStep(1); setProgress(0); };
    const pickMode = (m) => { setMode(m); setStep(1); setProgress(0); };

    const stepsByMode = mode === "langxin"
      ? ["配置授权", "同步进度", "预览完成"]
      : mode === "excel"
      ? ["上传文件", "字段映射", "预览完成"]
      : ["上传证件", "识别中", "预览完成"];

    return (
      <div>
        <div className="page-head">
          <div>
            <div className="page-title"><span className="accent"></span>数据导入</div>
            <div className="page-sub">支持朗新人事系统同步、Excel 批量导入、证件 OCR 识别三种方式</div>
          </div>
        </div>

        {mode && (
          <div className="steps">
            {stepsByMode.map((s, i) => (
              <React.Fragment key={i}>
                <div className={"step" + (step - 1 === i ? " active" : step - 1 > i ? " done" : "")}>
                  <div className="num">{step - 1 > i ? "✓" : i + 1}</div>
                  <span>{s}</span>
                </div>
                {i < stepsByMode.length - 1 && <div className="step-line"></div>}
              </React.Fragment>
            ))}
          </div>
        )}

        {/* 选模式 */}
        {!mode && (
          <div className="fade">
            <div className="import-modes">
              <button className="mode" onClick={() => pickMode("langxin")}>
                <div className="mi"><Icon name="sync" /></div>
                <h5>朗新系统同步</h5>
                <p>对接朗新人事系统，自动拉取在职人员花名册与变动数据，支持定时增量同步。</p>
                <div style={{marginTop:12}}><Badge color="blue">推荐</Badge></div>
              </button>
              <button className="mode" onClick={() => pickMode("excel")}>
                <div className="mi"><Icon name="file" /></div>
                <h5>Excel 批量导入</h5>
                <p>下载标准模板填写后上传，支持智能字段映射与数据校验，适合大批量初始化。</p>
              </button>
              <button className="mode" onClick={() => pickMode("ocr")}>
                <div className="mi"><Icon name="scan" /></div>
                <h5>证件 OCR 识别</h5>
                <p>扫描身份证 / 学位证自动识别关键字段，单条快速建档，适合新增干部录入。</p>
              </button>
            </div>
            <div className="alert info"><Icon name="bell" />数据导入遵循《干部人事档案管理规定》，敏感字段加密存储，操作全程留痕。</div>
          </div>
        )}

        {/* 朗新 步骤1：配置授权 */}
        {mode === "langxin" && step === 1 && (
          <div className="fade">
            <div className="sync-source">
              <div className="si">朗</div>
              <div className="sc">
                <div className="st">朗新人事管理系统 · 已对接</div>
                <div className="ss">api.langxin.gov.cn · 上次同步：2026-06-28 02:00 · 增量同步</div>
              </div>
              <Badge color="green" solid>已授权</Badge>
            </div>
            <div className="info-block">
              <h4><Icon name="settings" />同步配置</h4>
              <div className="dl">
                <Field k="同步范围" v="全单位在职人员" />
                <Field k="同步频率" v="每日 02:00 自动增量" />
                <Field k="数据项" v="基本信息 / 学历 / 职务 / 部门" />
                <Field k="本次预计" v="11 条变动数据" />
              </div>
            </div>
            <div style={{display:"flex",gap:10,marginTop:18}}>
              <button className="btn" onClick={reset}>取消</button>
              <button className="btn btn-primary" onClick={() => setStep(2)}><Icon name="sync" />开始同步</button>
            </div>
          </div>
        )}

        {/* 朗新 / OCR 步骤2：进度 */}
        {mode !== "excel" && step === 2 && (
          <div className="fade">
            <div className="info-block" style={{textAlign:"center",padding:"48px 24px"}}>
              <div style={{width:72,height:72,borderRadius:"50%",background: progress >= 100 ? "#DCFCE7" : "var(--blue-light)",color: progress >= 100 ? "var(--success)" : "var(--blue)",display:"flex",alignItems:"center",justifyContent:"center",margin:"0 auto 18px"}}>
                <Icon name={progress >= 100 ? "check" : (mode === "ocr" ? "scan" : "sync")} size={34} />
              </div>
              <h4 style={{fontSize:18,marginBottom:8}}>{progress >= 100 ? (mode === "ocr" ? "识别完成" : "同步完成") : (mode === "ocr" ? "正在识别证件信息…" : "正在同步朗新数据…")}</h4>
              <div style={{fontSize:13,color:"var(--text2)",marginBottom:20}}>{progress >= 100 ? "已获取 11 条变动数据，请预览确认" : "已处理 " + Math.floor(progress / 100 * 11) + " / 11 条"}</div>
              <div style={{maxWidth:420,margin:"0 auto"}}>
                <div className="progress"><div className="progress-bar" style={{width: progress + "%"}}></div></div>
                <div style={{fontSize:12,color:"var(--text3)",marginTop:6}}>{progress}%</div>
              </div>
            </div>
          </div>
        )}

        {/* Excel 步骤1：上传 */}
        {mode === "excel" && step === 1 && (
          <div className="fade">
            <div className="alert info" style={{marginBottom:18}}><Icon name="download" />请使用标准模板填写，<a href="#" style={{color:"var(--red)",fontWeight:600}}>点此下载《干部信息导入模板.xlsx》</a></div>
            <div className="dropzone" onClick={() => setStep(2)}>
              <div className="di"><Icon name="upload" size={26} /></div>
              <h4>点击上传 Excel 文件，或将文件拖拽到此</h4>
              <p>支持 .xlsx / .xls 格式，单文件不超过 20MB</p>
            </div>
            <div style={{display:"flex",gap:10,marginTop:18}}>
              <button className="btn" onClick={reset}>取消</button>
            </div>
          </div>
        )}

        {/* Excel 步骤2：字段映射 */}
        {mode === "excel" && step === 2 && (
          <div className="fade">
            <div className="info-block">
              <h4><Icon name="database" />字段映射 · 智能匹配</h4>
              <table className="field-map-table">
                <thead><tr><th>系统字段</th><th>Excel 列名</th><th>示例值</th><th>状态</th></tr></thead>
                <tbody>
                  {[["姓名","姓名","陈志远"],["性别","sex","男"],["出生年月","出生日期","1972-03"],
                    ["部门","所在部门","党委办公室"],["职务","岗位","党委书记"],["职级","级别","正处级"],
                    ["政治面貌","党派","中共党员"],["学历","最高学历","博士研究生"],["联系电话","手机号","138****6201"]].map((r,i) => (
                    <tr key={i}>
                      <td style={{fontWeight:600}}>{r[0]}</td>
                      <td>{r[1]} <span className="arrow">→</span></td>
                      <td style={{color:"var(--text2)"}}>{r[2]}</td>
                      <td><Badge color="green">已匹配</Badge></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <div style={{display:"flex",gap:10,marginTop:18}}>
              <button className="btn" onClick={() => setStep(1)}>上一步</button>
              <button className="btn btn-primary" onClick={() => setStep(3)}><Icon name="check" />确认映射，开始导入</button>
            </div>
          </div>
        )}

        {/* OCR 步骤1：上传 */}
        {mode === "ocr" && step === 1 && (
          <div className="fade">
            <div className="dropzone" onClick={() => setStep(2)}>
              <div className="di"><Icon name="scan" size={26} /></div>
              <h4>点击上传证件照片或扫描件</h4>
              <p>支持 jpg / png / pdf，单次最多 10 张</p>
            </div>
            <div style={{display:"flex",gap:10,marginTop:18}}>
              <button className="btn" onClick={reset}>取消</button>
            </div>
          </div>
        )}

        {/* 步骤3：预览结果（三种模式共用） */}
        {step === 3 && (
          <div className="fade">
            <div className="stat-grid">
              <div className="stat"><div className="lbl">本次处理</div><div className="val">{result.total}<small>条</small></div></div>
              <div className="stat"><div className="lbl">新增干部</div><div className="val" style={{color:"var(--success)"}}>{result.newCount}<small>人</small></div></div>
              <div className="stat"><div className="lbl">更新信息</div><div className="val" style={{color:"var(--warning)"}}>{result.updateCount}<small>人</small></div></div>
              <div className="stat"><div className="lbl">失败 / 待确认</div><div className="val" style={{color:"var(--danger)"}}>{result.failCount}<small>条</small></div></div>
            </div>

            <div className="info-block">
              <h4><Icon name="file" />数据预览（{mode === "langxin" ? "同步" : "导入"}结果）</h4>
              <div className="preview-row">
                <Avatar cadre={{avatar:"宋",gender:"男"}} size={36} />
                <div style={{flex:1}}>
                  <div style={{fontWeight:600}}>宋明远 · C20260025</div>
                  <div style={{fontSize:12,color:"var(--text2)"}}>技术研发中心 · 副主任 · 副处级</div>
                </div>
                <span className="tag-chg tag-new">新增</span>
                <Icon name="chevronRight" style={{color:"var(--text3)"}} />
              </div>
              <div className="preview-row">
                <Avatar cadre={{avatar:"陈",gender:"男"}} size={36} />
                <div style={{flex:1}}>
                  <div style={{fontWeight:600}}>陈志远 · C20260001</div>
                  <div style={{fontSize:12,color:"var(--text2)"}}>党委办公室 · 党委书记 — 职务更新</div>
                </div>
                <span className="tag-chg tag-upd">更新</span>
                <Icon name="chevronRight" style={{color:"var(--text3)"}} />
              </div>
              <div className="preview-row">
                <Avatar cadre={{avatar:"高",gender:"女"}} size={36} />
                <div style={{flex:1}}>
                  <div style={{fontWeight:600}}>高芸 · C20260026</div>
                  <div style={{fontSize:12,color:"var(--text2)"}}>市场营销部 · 科长 — 部门调整</div>
                </div>
                <span className="tag-chg tag-upd">更新</span>
                <Icon name="chevronRight" style={{color:"var(--text3)"}} />
              </div>
              <div className="alert warn" style={{marginTop:12}}><Icon name="bell" />1 条数据存在「学历字段为空」，已标记待人工确认。</div>
            </div>

            <div style={{display:"flex",gap:10,padding:"18px 0 0"}}>
              <button className="btn" onClick={reset}><Icon name="refresh" />再次导入</button>
              <div style={{flex:1}}></div>
              <button className="btn btn-primary" onClick={reset}><Icon name="check" />确认入库</button>
            </div>
          </div>
        )}
      </div>
    );
  }

  // 挂载
  const root = ReactDOM.createRoot(document.getElementById("root"));
  root.render(React.createElement(App));
})();
