<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<title>高企资料收集清单</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  :root {
    --primary: #1e3a5f;
    --primary-light: #2c5282;
    --primary-bg: #ebf2fa;
    --bg: #f5f7fa;
    --card: #ffffff;
    --border: #e2e8f0;
    --text: #1a202c;
    --text-secondary: #64748b;
    --received: #16a34a;
    --received-bg: #dcfce7;
    --received-border: #86efac;
    --missing: #dc2626;
    --missing-bg: #fef2f2;
    --missing-border: #fecaca;
  }
  body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    background: var(--bg);
    color: var(--text);
    min-width: 1280px;
    line-height: 1.5;
  }

  /* 顶部导航 */
  .header {
    background: var(--primary); color: #fff;
    padding: 16px 32px;
    display: flex; align-items: center; justify-content: space-between;
    box-shadow: 0 2px 8px rgba(30,58,95,0.15);
  }
  .header-left { display: flex; align-items: center; gap: 16px; }
  .header-logo {
    width: 36px; height: 36px; background: rgba(255,255,255,0.15);
    border-radius: 8px; display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 14px;
  }
  .header h1 { font-size: 18px; font-weight: 600; }
  .header-sub { font-size: 12px; opacity: 0.75; margin-top: 2px; }
  .search-box {
    background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.2);
    border-radius: 6px; padding: 7px 14px; color: #fff; font-size: 13px;
    width: 240px; outline: none;
  }
  .search-box::placeholder { color: rgba(255,255,255,0.6); }

  /* 统计卡片 */
  .stats-row { display: grid; grid-template-columns: repeat(4,1fr); gap:16px; padding:24px 32px 0; }
  .stat-card { background:var(--card); border-radius:10px; padding:18px 20px; border:1px solid var(--border); }
  .stat-label { font-size:12px; color:var(--text-secondary); margin-bottom:6px; }
  .stat-value { font-size:28px; font-weight:700; line-height:1.1; }
  .stat-value.green { color:var(--received); }
  .stat-value.red { color:var(--missing); }
  .stat-value.blue { color:var(--primary); }
  .stat-hint { font-size:11px; color:var(--text-secondary); margin-top:4px; }

  /* 工具栏 */
  .toolbar { display:flex; justify-content:space-between; align-items:center; padding:20px 32px 12px; }
  .toolbar-left { display:flex; align-items:center; gap:12px; }
  .toolbar h2 { font-size:16px; font-weight:600; }
  .badge-count { background:var(--primary-bg); color:var(--primary); font-size:12px; font-weight:600; padding:2px 10px; border-radius:10px; }
  .btn {
    border:none; border-radius:6px; padding:8px 16px; font-size:13px; font-weight:500;
    cursor:pointer; transition:all .15s; display:inline-flex; align-items:center; gap:6px;
  }
  .btn-primary { background:var(--primary); color:#fff; }
  .btn-primary:hover { background:var(--primary-light); }
  .btn-outline { background:#fff; border:1px solid var(--border); color:var(--text); }
  .btn-outline:hover { background:var(--bg); }
  .btn-danger { background:#fff; border:1px solid var(--missing-border); color:var(--missing); padding:5px 10px; font-size:12px; }
  .btn-danger:hover { background:var(--missing-bg); }

  /* 筛选 */
  .filter-group { display:flex; align-items:center; gap:14px; }
  .filter-radio {
    display:flex; align-items:center; gap:8px; cursor:pointer; font-size:13px;
    user-select:none; padding:6px 14px; border-radius:8px; border:1.5px solid var(--border);
    background:#fff; transition:all .15s;
  }
  .filter-radio:hover { border-color:#cbd5e1; }
  .filter-radio input { display:none; }
  .filter-box {
    width:20px; height:20px; border-radius:5px; border:2px solid var(--border);
    display:inline-flex; align-items:center; justify-content:center;
    font-size:12px; color:#fff; font-weight:700;
  }
  .filter-radio[data-val="true"] .filter-box { border-color:var(--received-border); background:var(--received-bg); color:var(--received); }
  .filter-radio[data-val="false"] .filter-box { border-color:var(--missing-border); background:var(--missing-bg); color:var(--missing); }
  .filter-radio.active[data-val="true"] { border-color:var(--received); background:var(--received-bg); color:var(--received); font-weight:600; }
  .filter-radio.active[data-val="false"] { border-color:var(--missing); background:var(--missing-bg); color:var(--missing); font-weight:600; }
  .filter-radio.active[data-val="true"] .filter-box { background:var(--received); }
  .filter-radio.active[data-val="false"] .filter-box { background:var(--missing); }
  .filter-radio.active .filter-box::after { content:"✓"; }

  /* 表格 */
  .table-wrap { margin:0 32px 32px; background:var(--card); border-radius:10px; border:1px solid var(--border); overflow-x:auto; }
  table { width:100%; border-collapse:collapse; font-size:13px; min-width:1100px; }
  thead th {
    background:#f8fafc; padding:12px 10px; text-align:center; font-weight:600;
    color:var(--text-secondary); font-size:12px; border-bottom:2px solid var(--border); white-space:nowrap;
  }
  thead th:first-child { text-align:left; padding-left:20px; min-width:200px; }
  thead th.col-action { min-width:80px; }
  tbody td { padding:10px; text-align:center; border-bottom:1px solid var(--border); vertical-align:middle; }
  tbody tr:hover { background:#fafbfd; }
  tbody tr:last-child td { border-bottom:none; }
  .company-cell { text-align:left; padding-left:20px; display:flex; align-items:center; gap:10px; }
  .company-avatar {
    width:32px; height:32px; border-radius:6px; background:var(--primary-bg); color:var(--primary);
    display:flex; align-items:center; justify-content:center; font-weight:700; font-size:13px; flex-shrink:0;
  }
  .company-name { font-weight:600; font-size:13px; }
  .company-meta { font-size:11px; color:var(--text-secondary); }
  .status-cell { cursor:pointer; }
  .status-badge {
    display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px;
    border-radius:6px; font-size:14px; transition:all .15s;
  }
  .status-badge.received { background:var(--received-bg); color:var(--received); }
  .status-badge.missing { background:var(--missing-bg); color:var(--missing); }
  .status-cell:hover .status-badge { transform:scale(1.1); }
  .progress-wrap { display:flex; align-items:center; gap:8px; justify-content:center; }
  .progress-bar { width:70px; height:6px; background:var(--border); border-radius:3px; overflow:hidden; }
  .progress-fill { height:100%; background:var(--received); border-radius:3px; transition:width .3s; }
  .progress-text { font-size:11px; color:var(--text-secondary); white-space:nowrap; }
  .progress-text.done { color:var(--received); font-weight:600; }

  /* 弹窗 */
  .modal-mask {
    position:fixed; inset:0; background:rgba(0,0,0,0.4); display:none;
    align-items:center; justify-content:center; z-index:100;
  }
  .modal-mask.show { display:flex; }
  .modal { background:#fff; border-radius:12px; padding:28px; width:420px; box-shadow:0 20px 60px rgba(0,0,0,0.2); }
  .modal h3 { font-size:17px; margin-bottom:16px; }
  .modal label { display:block; font-size:12px; color:var(--text-secondary); margin-bottom:6px; }
  .modal input {
    width:100%; padding:10px 12px; border:1px solid var(--border); border-radius:6px;
    font-size:14px; outline:none; transition:border-color .15s;
  }
  .modal input:focus { border-color:var(--primary); }
  .modal-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:20px; }

  .empty-state { text-align:center; padding:60px 20px; color:var(--text-secondary); }
  .empty-state-icon { font-size:40px; margin-bottom:12px; opacity:0.4; }
  .empty-state p { font-size:14px; margin-bottom:16px; }

  .legend { display:flex; gap:16px; align-items:center; font-size:12px; color:var(--text-secondary); }
  .legend-item { display:flex; align-items:center; gap:6px; }
  .legend-dot { width:12px; height:12px; border-radius:3px; }
  .legend-dot.received { background:var(--received-bg); border:1px solid var(--received-border); }
  .legend-dot.missing { background:var(--missing-bg); border:1px solid var(--missing-border); }

  .toast {
    position:fixed; top:24px; right:24px; background:var(--text); color:#fff;
    padding:10px 18px; border-radius:6px; font-size:13px; opacity:0;
    transform:translateY(-10px); transition:all .25s; z-index:200; pointer-events:none;
  }
  .toast.show { opacity:1; transform:translateY(0); }
</style>
</head>
<body>

<header class="header">
  <div class="header-left">
    <div class="header-logo">高企</div>
    <div>
      <h1>高企资料收集清单</h1>
      <div class="header-sub">高新技术企业认定 · 申报材料进度追踪</div>
    </div>
  </div>
  <input type="text" class="search-box" id="searchInput" placeholder="搜索公司名称…">
</header>

<div class="stats-row">
  <div class="stat-card"><div class="stat-label">申报企业总数</div><div class="stat-value blue" id="statTotal">0</div><div class="stat-hint">当前跟踪的企业数量</div></div>
  <div class="stat-card"><div class="stat-label">已收到资料项</div><div class="stat-value green" id="statReceived">0</div><div class="stat-hint">共 12 项 / 每家</div></div>
  <div class="stat-card"><div class="stat-label">待收集资料项</div><div class="stat-value red" id="statMissing">0</div><div class="stat-hint">点击单元格可切换状态</div></div>
  <div class="stat-card"><div class="stat-label">整体完成率</div><div class="stat-value" id="statRate" style="color:var(--primary)">0%</div><div class="stat-hint">已收资料 / 应收资料</div></div>
</div>

<div class="toolbar">
  <div class="toolbar-left">
    <h2>企业资料进度</h2>
    <span class="badge-count" id="companyCount">0 家</span>
    <div class="legend" style="margin-left:16px">
      <div class="legend-item"><span class="legend-dot received"></span>已收到</div>
      <div class="legend-item"><span class="legend-dot missing"></span>未收到</div>
    </div>
  </div>
  <div style="display:flex;align-items:center;gap:12px">
    <div class="filter-group">
      <label class="filter-radio" data-val="true" onclick="setFilter(true)">
        <input type="radio" name="matFilter"><span class="filter-box"></span>已收到
      </label>
      <label class="filter-radio" data-val="false" onclick="setFilter(false)">
        <input type="radio" name="matFilter"><span class="filter-box"></span>未收到
      </label>
      <button class="btn btn-outline" id="clearFilterBtn" onclick="clearFilter()" style="display:none">清除筛选</button>
    </div>
    <button class="btn btn-primary" onclick="openAddModal()">+ 添加公司</button>
  </div>
</div>

<div class="table-wrap">
  <table>
    <thead><tr id="tableHead"></tr></thead>
    <tbody id="tableBody"></tbody>
  </table>
</div>

<div class="modal-mask" id="addModal">
  <div class="modal">
    <h3>添加申报企业</h3>
    <label>公司名称</label>
    <input type="text" id="newCompanyName" placeholder="请输入公司全称">
    <div class="modal-actions">
      <button class="btn btn-outline" onclick="closeAddModal()">取消</button>
      <button class="btn btn-primary" onclick="addCompany()">确认添加</button>
    </div>
  </div>
</div>

<div class="toast" id="toast"></div>

<script>
// 资料项从PHP输出
const MATERIALS = {"license":"营业执照","intro":"公司简介","ip":"知识产权","software":"软著手册","salesContract":"销售合同","invoice":"发票","equipment":"研发设备清单","roster":"人员花名册","laborContract":"科技人员劳动合同","socialSecurity":"社保证明","diploma":"毕业证书","registerForm":"企业注册登记表"};
const API = 'api/index.php';

let companies = [];
let currentFilter = null;

// ===== API 封装 =====
async function apiGet(action, params = {}) {
  const qs = new URLSearchParams(params).toString();
  const res = await fetch(`${API}?action=${action}${qs ? '&' + qs : ''}`);
  return res.json();
}
async function apiPost(action, data = {}) {
  const res = await fetch(`${API}?action=${action}`, {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
  });
  return res.json();
}

// ===== 加载数据 =====
async function loadData() {
  const kw = document.getElementById('searchInput').value.trim();
  const [listRes, statRes] = await Promise.all([
    apiGet('list', {keyword: kw}),
    apiGet('stats')
  ]);
  companies = listRes.data || [];
  render();
  // 更新统计
  document.getElementById('statTotal').textContent = statRes.total;
  document.getElementById('companyCount').textContent = statRes.total + ' 家';
  document.getElementById('statReceived').textContent = statRes.recv;
  document.getElementById('statMissing').textContent = statRes.missing;
  document.getElementById('statRate').textContent = statRes.rate + '%';
}

// ===== 渲染 =====
function render() {
  const head = document.getElementById('tableHead');
  let h = '<th>公司名称</th>';
  Object.entries(MATERIALS).forEach(([k, name]) => h += `<th title="${name}">${name}</th>`);
  h += '<th class="col-action">收集进度</th><th class="col-action">操作</th>';
  head.innerHTML = h;

  const body = document.getElementById('tableBody');
  // 筛选：只保留有符合条件资料的公司
  let visible = companies;
  if (currentFilter !== null) {
    visible = companies.filter(c =>
      Object.values(c.materials).some(v => !!v === currentFilter)
    );
  }
  if (visible.length === 0) {
    body.innerHTML = `<tr><td colspan="${Object.keys(MATERIALS).length + 3}"><div class="empty-state">
      <div class="empty-state-icon">📋</div>
      <p>${currentFilter === null ? '暂无公司，点击右上角「添加公司」开始' : (currentFilter ? '没有已收到的资料项' : '所有资料均已收齐，太棒了！')}</p>
    </div></td></tr>`;
  } else {
    body.innerHTML = visible.map(c => {
      const total = Object.keys(MATERIALS).length;
      const recv = Object.values(c.materials).filter(v => v).length;
      const pct = Math.round(recv / total * 100);
      const done = recv === total;
      const initial = c.name.charAt(0);
      let cells = Object.entries(MATERIALS).map(([k, name]) => {
        const got = !!c.materials[k];
        if (currentFilter !== null && got !== currentFilter) {
          return `<td style="background:#fafbfd;color:#e2e8f0">·</td>`;
        }
        return `<td class="status-cell" onclick="toggleMaterial(${c.id},'${k}')" title="${name}: ${got ? '已收到（点击切换为未收到）' : '未收到（点击标记为已收到）'}">
          <span class="status-badge ${got ? 'received' : 'missing'}">${got ? '✓' : '—'}</span>
        </td>`;
      }).join('');
      return `<tr>
        <td><div class="company-cell">
          <div class="company-avatar">${initial}</div>
          <div><div class="company-name">${c.name}</div><div class="company-meta">已收 ${recv}/${total} 项</div></div>
        </div></td>
        ${cells}
        <td><div class="progress-wrap">
          <div class="progress-bar"><div class="progress-fill" style="width:${pct}%"></div></div>
          <span class="progress-text ${done ? 'done' : ''}">${done ? '完成' : pct + '%'}</span>
        </div></td>
        <td><button class="btn btn-danger" onclick="deleteCompany(${c.id},'${c.name}')">删除</button></td>
      </tr>`;
    }).join('');
  }
}

// ===== 交互 =====
async function toggleMaterial(id, key) {
  await apiPost('toggle', {company_id: id, material_key: key});
  await loadData();
}
async function deleteCompany(id, name) {
  if (!confirm(`确认删除「${name}」及其收集进度？`)) return;
  await apiPost('delete', {id});
  showToast(`已删除「${name}」`);
  await loadData();
}
function openAddModal() {
  document.getElementById('newCompanyName').value = '';
  document.getElementById('addModal').classList.add('show');
  setTimeout(() => document.getElementById('newCompanyName').focus(), 100);
}
function closeAddModal() { document.getElementById('addModal').classList.remove('show'); }
async function addCompany() {
  const name = document.getElementById('newCompanyName').value.trim();
  if (!name) { alert('请输入公司名称'); return; }
  const res = await apiPost('add', {name});
  if (!res.ok) { alert(res.msg); return; }
  closeAddModal();
  showToast(`已添加「${name}」`);
  await loadData();
}
function setFilter(val) {
  currentFilter = (currentFilter === val) ? null : val;
  updateFilterUI();
  render();
}
function clearFilter() {
  currentFilter = null;
  updateFilterUI();
  render();
}
function updateFilterUI() {
  document.querySelectorAll('.filter-radio').forEach(lb => {
    const v = lb.dataset.val === 'true';
    lb.classList.toggle('active', currentFilter === v);
    lb.querySelector('input').checked = (currentFilter === v);
  });
  document.getElementById('clearFilterBtn').style.display = (currentFilter === null) ? 'none' : 'inline-flex';
}
function showToast(msg) {
  const t = document.getElementById('toast');
  t.textContent = msg;
  t.classList.add('show');
  clearTimeout(t._timer);
  t._timer = setTimeout(() => t.classList.remove('show'), 1800);
}

document.getElementById('searchInput').addEventListener('input', () => { clearTimeout(window._st); window._st = setTimeout(loadData, 300); });
document.getElementById('newCompanyName').addEventListener('keydown', e => { if (e.key === 'Enter') addCompany(); });
document.getElementById('addModal').addEventListener('click', e => { if (e.target.id === 'addModal') closeAddModal(); });

// 初始化
loadData();
</script>
</body>
</html>
