/* ===== pages-dashboard.jsx — / + /alerts ===== */
(function () {
  const { Icon, Button, IconBtn, Card, Badge, AlarmChip, EmptyState, Avatar,
    useStore, navigate, cls, ALARM_META, fmtRel, fmtDate, fmtQty } = window;

  /* ---------- Dashboard ---------- */
  function Dashboard({ mobile }) {
    const store = useStore();
    const { allAlarms, activity, users, currentUser, currentUserId, reagent_products, reagent_batches, device_products, device_units, suppliers, customers } = store;
    // Real logged-in user from /auth/me, fallback to users lookup for legacy
    const u = currentUser || users.find((x) => x.id === currentUserId);

    // Group alarms by type
    const byType = window.groupBy(allAlarms, (a) => a.type);
    const REAGENT_TYPES = ['EXPIRED', 'EXPIRING', 'LOW_STOCK', 'OUTFLOW_OVER', 'STALE'];
    const DEVICE_TYPES = ['DEVICE_FAULT', 'REPAIR_OVER'];

    const reagentTotal = REAGENT_TYPES.reduce((acc, t) => acc + (byType.get(t)?.length || 0), 0);
    const deviceTotal = DEVICE_TYPES.reduce((acc, t) => acc + (byType.get(t)?.length || 0), 0);

    const stats = [
      { label: '在库批次', value: reagent_batches.filter(b => b.on_hand_boxes > 0).length, sub: `共 ${reagent_batches.length} 条` },
      { label: '试剂 SKU', value: reagent_products.length, sub: '产品目录' },
      { label: '设备 (SN)', value: device_units.filter(u=>u.has_sn).length, sub: `${device_units.filter(u=>!u.has_sn).length} 项 SN 缺失` },
      { label: '客户 / 供货商', value: `${customers.length} / ${suppliers.filter(s=>!s.archived).length}`, sub: '已激活' },
    ];

    return (
      <div className={cls(mobile ? 'p-3' : 'p-6')}>
        {/* Greeting */}
        <div className={cls('flex items-end justify-between gap-3', mobile ? 'mb-4' : 'mb-6')}>
          <div>
            <div className="text-[11px] uppercase tracking-wider text-ink-500 font-mono">
              {new Date().toLocaleDateString('zh-CN', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })}
            </div>
            <h1 className={cls('font-semibold tracking-tight text-ink-900 mt-1',
              mobile ? 'text-xl' : 'text-2xl')}>
              {u?.name || u?.email || '欢迎'}
            </h1>
            {!mobile && (
              <p className="text-sm text-ink-500 mt-1">
                今天有 <span className="font-medium text-red-700">{allAlarms.length}</span> 个待处理报警 ·
                <span className="text-ink-700"> {reagentTotal}</span> 试剂 ·
                <span className="text-ink-700"> {deviceTotal}</span> 设备
              </p>
            )}
          </div>
          {!mobile && (
            <div className="flex items-center gap-2">
              <Button variant="secondary" size="sm" icon={Icon.download}>导出周报</Button>
              <Button size="sm" icon={Icon.plus} onClick={() => navigate('/reagents/outflow/new')}>取货</Button>
            </div>
          )}
        </div>

        {/* Stats strip — desktop only */}
        {!mobile && (
          <div className="grid grid-cols-4 gap-3 mb-5">
            {stats.map((s) => (
              <Card key={s.label} className="p-4">
                <div className="text-[11px] uppercase tracking-wider text-ink-500">{s.label}</div>
                <div className="mt-1.5 flex items-baseline gap-2">
                  <div className="text-2xl font-semibold tracking-tight tabular-nums font-mono">{s.value}</div>
                </div>
                <div className="text-[11px] text-ink-500 mt-0.5">{s.sub}</div>
              </Card>
            ))}
          </div>
        )}

        {/* Alarm grid */}
        <div className={cls(mobile ? 'mb-5' : 'mb-6')}>
          <div className="flex items-baseline justify-between mb-2.5">
            <h2 className="text-sm font-semibold tracking-tight">实时报警</h2>
            <button onClick={() => navigate('/alerts')}
              className="text-xs text-ink-500 hover:text-ink-900 inline-flex items-center gap-1">
              全部 <Icon.arrowR size={12} />
            </button>
          </div>

          {/* Reagent row */}
          <div className="text-[10px] uppercase tracking-wider text-ink-400 mb-1.5 mt-1">模块 R · 试剂（5 种）</div>
          <div className={cls('grid gap-2 mb-3',
            mobile ? 'grid-cols-2' : 'grid-cols-5')}>
            {REAGENT_TYPES.map((t) => (
              <AlarmCard key={t} type={t} items={byType.get(t) || []} mobile={mobile} />
            ))}
          </div>

          <div className="text-[10px] uppercase tracking-wider text-ink-400 mb-1.5">模块 D · 设备（2 种）</div>
          <div className={cls('grid gap-2',
            mobile ? 'grid-cols-2' : 'grid-cols-5')}>
            {DEVICE_TYPES.map((t) => (
              <AlarmCard key={t} type={t} items={byType.get(t) || []} mobile={mobile} />
            ))}
            {!mobile && (
              <Card className="col-span-3 p-4 bg-gradient-to-br from-ink-900 to-ink-950 text-white relative overflow-hidden">
                <div className="absolute inset-0 dot-bg opacity-[0.05]"></div>
                <div className="relative">
                  <h3 className="text-base font-semibold tracking-tight">Firsteck Bio · 实验室库存</h3>
                  <p className="text-xs text-ink-400 mt-1 max-w-[26rem] leading-relaxed">
                    入库 → 内仓 → 客户 → 客户 → 内仓 全链路追踪。试剂按批次（盒+test），设备按 SN。
                  </p>
                  <div className="mt-3 flex items-center gap-2 text-[11px]">
                    <Badge tone="green" dot="bg-emerald-400">系统在线</Badge>
                  </div>
                </div>
              </Card>
            )}
          </div>
        </div>

        {/* Bottom: alarms detail + activity */}
        <div className={cls('grid gap-4',
          mobile ? 'grid-cols-1' : 'grid-cols-3')}>
          {/* Top alarms list */}
          <Card className={cls('overflow-hidden', mobile ? '' : 'col-span-2')}>
            <div className="flex items-center justify-between px-4 h-11 border-b border-ink-100">
              <h3 className="text-sm font-semibold">优先处理</h3>
              <button onClick={() => navigate('/alerts')} className="text-xs text-ink-500 hover:text-ink-900">查看全部 ({allAlarms.length})</button>
            </div>
            {allAlarms.length === 0 ? (
              <EmptyState title="🎉 当前无报警" hint="所有库存与设备状态正常" compact />
            ) : (
              <ul>
                {allAlarms.slice(0, mobile ? 4 : 6).map((a, i) => (
                  <AlarmRow key={i} a={a} />
                ))}
              </ul>
            )}
          </Card>

          {/* Activity */}
          <Card className="overflow-hidden">
            <div className="flex items-center justify-between px-4 h-11 border-b border-ink-100">
              <h3 className="text-sm font-semibold">最近活动</h3>
              <span className="text-[10px] text-ink-400 font-mono uppercase tracking-wider">实时</span>
            </div>
            <ul className="divide-y divide-ink-100">
              {activity.slice(0, mobile ? 5 : 7).map((a) => {
                const user = users.find((u) => u.id === a.actor);
                const kindMeta = {
                  outflow:  { icon: Icon.arrowR,  tone: 'bg-sky-100 text-sky-700' },
                  return:   { icon: Icon.arrowL,  tone: 'bg-emerald-100 text-emerald-700' },
                  transfer: { icon: Icon.truck,   tone: 'bg-violet-100 text-violet-700' },
                  receive:  { icon: Icon.pkg,     tone: 'bg-amber-100 text-amber-800' },
                  fault:    { icon: Icon.tool,    tone: 'bg-rose-100 text-rose-700' },
                  edit:     { icon: Icon.edit,    tone: 'bg-ink-100 text-ink-700' },
                };
                const m = kindMeta[a.kind] || kindMeta.edit;
                return (
                  <li key={a.id} className="px-4 py-2.5 flex gap-2.5">
                    <span className={cls('h-7 w-7 rounded-md shrink-0 inline-flex items-center justify-center', m.tone)}>
                      <m.icon size={13} />
                    </span>
                    <div className="flex-1 min-w-0 leading-snug">
                      <div className="text-[12.5px] text-ink-800">{a.text}</div>
                      <div className="text-[11px] text-ink-400 mt-0.5 flex items-center gap-1.5">
                        <span>{user?.name}</span>
                        <span>·</span>
                        <span>{relTime(a.ts)}</span>
                      </div>
                    </div>
                  </li>
                );
              })}
            </ul>
          </Card>
        </div>
      </div>
    );
  }

  function relTime(ts) {
    const d = new Date(ts);
    const now = new Date();
    const diff = (now - d) / 1000;
    if (diff < 60) return '刚刚';
    if (diff < 3600) return Math.floor(diff / 60) + ' 分钟前';
    if (diff < 86400) return Math.floor(diff / 3600) + ' 小时前';
    return Math.floor(diff / 86400) + ' 天前';
  }

  /* ---------- Alarm cards ---------- */
  function AlarmCard({ type, items, mobile }) {
    const m = ALARM_META[type];
    const count = items.length;
    const active = count > 0;
    return (
      <button onClick={() => navigate(`/alerts?type=${type}`)}
        className={cls(
          'group text-left rounded-xl p-3 ring-1 transition-all hover:shadow-card hover:-translate-y-px',
          active
            ? `${m.tw} ring-2 hover:ring-2 hover:ring-offset-1`
            : 'bg-white ring-ink-200 hover:bg-ink-50'
        )}
        style={active ? { boxShadow: `inset 0 0 0 0 transparent` } : undefined}>
        <div className="flex items-start justify-between mb-1.5">
          <span className={cls('h-7 w-7 rounded-md inline-flex items-center justify-center text-base',
            active ? 'bg-white/60' : 'bg-ink-100')}>
            {m.emoji}
          </span>
          {active && (
            <Icon.arrowR size={12} className={cls('opacity-0 group-hover:opacity-100 transition-opacity')} />
          )}
        </div>
        <div className={cls('font-mono tabular-nums font-semibold tracking-tight',
          mobile ? 'text-xl' : 'text-2xl',
          active ? '' : 'text-ink-300')}>
          {count}
        </div>
        <div className={cls('text-[11px] font-medium mt-0.5', active ? '' : 'text-ink-500')}>
          {m.label}
        </div>
      </button>
    );
  }

  /* ---------- AlarmRow (shared) ---------- */
  function AlarmRow({ a, dense }) {
    const m = ALARM_META[a.type];
    const store = useStore();
    let title = '', sub = '', route = '/alerts';
    if (a.scope === 'reagent' && a.entityKind === 'batch') {
      title = a.product?.name || '?';
      sub = `批号 ${a.entity.lot} · 剩 ${fmtQty(a.entity.on_hand_boxes, a.entity.on_hand_atoms)}`;
      route = `/reagents/batches/${a.entity.id}`;
    } else if (a.scope === 'reagent' && a.entityKind === 'outflow') {
      const cust = store.customers.find((c) => c.id === a.entity.customer_id);
      title = `${a.product?.name} → ${cust?.short || cust?.name}`;
      sub = `取出 ${fmtQty(a.entity.taken_boxes, a.entity.taken_atoms)} · 应还 ${a.entity.due_at}`;
      route = `/reagents/batches/${a.batch?.id}`;
    } else if (a.scope === 'device') {
      title = `${a.product?.name} · ${a.entity.sn || '(SN 缺失)'}`;
      sub = a.detail;
      route = `/devices/units/${a.entity.id}`;
    }

    return (
      <li onClick={() => navigate(route)}
        className={cls('px-4 flex items-center gap-3 cursor-pointer hover:bg-ink-50 border-b border-ink-100 last:border-0',
          dense ? 'py-2' : 'py-3')}>
        <span className={cls('h-2 w-2 rounded-full shrink-0', m.dot)}></span>
        <span className="text-base shrink-0 w-5 text-center">{m.emoji}</span>
        <div className="flex-1 min-w-0">
          <div className="text-sm text-ink-900 truncate">{title}</div>
          <div className="text-xs text-ink-500 truncate">{sub}</div>
        </div>
        <span className={cls('text-[11px] px-1.5 py-0.5 rounded-md ring-1 font-medium shrink-0', m.tw)}>
          {a.detail}
        </span>
        <Icon.chevRight size={14} className="text-ink-300 shrink-0" />
      </li>
    );
  }

  /* ---------- Alerts page ---------- */
  function AlertsPage({ mobile }) {
    const { allAlarms } = useStore();
    const initialType = (window.location.search.match(/type=([^&]+)/) || [])[1];
    const [filter, setFilter] = React.useState(initialType || 'ALL');
    const [scope, setScope] = React.useState('ALL');

    const filtered = allAlarms.filter((a) => {
      if (filter !== 'ALL' && a.type !== filter) return false;
      if (scope !== 'ALL' && a.scope !== scope) return false;
      return true;
    });

    const counts = (t) => allAlarms.filter((a) => a.type === t).length;

    return (
      <div className={cls(mobile ? 'p-3' : 'p-6')}>
        <div className={cls('flex items-end justify-between gap-3', mobile ? 'mb-3' : 'mb-5')}>
          <div>
            <h1 className={cls('font-semibold tracking-tight', mobile ? 'text-lg' : 'text-2xl')}>全部报警</h1>
            <p className="text-xs text-ink-500 mt-1">共 {allAlarms.length} 个未处理 · 按严重程度排序</p>
          </div>
          {!mobile && (
            <div className="flex items-center gap-2">
              <Button variant="secondary" size="sm" icon={Icon.download}>导出 CSV</Button>
              <Button variant="secondary" size="sm" icon={Icon.refresh}>刷新</Button>
            </div>
          )}
        </div>

        {/* Filter chips */}
        <div className={cls('flex flex-wrap gap-1.5', mobile ? 'mb-3' : 'mb-4')}>
          <FilterChip active={filter === 'ALL'} onClick={() => setFilter('ALL')}>
            全部 <span className="ml-1 text-ink-400 font-mono">{allAlarms.length}</span>
          </FilterChip>
          {Object.keys(ALARM_META).map((t) => {
            const m = ALARM_META[t]; const n = counts(t);
            return (
              <FilterChip key={t} active={filter === t} onClick={() => setFilter(t)} disabled={n === 0}>
                <span>{m.emoji}</span> {m.label} <span className="ml-0.5 text-ink-400 font-mono">{n}</span>
              </FilterChip>
            );
          })}
        </div>

        <Card className="overflow-hidden">
          <div className="flex items-center justify-between px-4 h-11 border-b border-ink-100">
            <div className="text-xs text-ink-500">显示 {filtered.length} 条</div>
            <div className="flex items-center gap-1 text-[11px]">
              {['ALL','reagent','device'].map((s) => (
                <button key={s} onClick={() => setScope(s)}
                  className={cls('h-7 px-2 rounded-md transition-colors',
                    scope === s ? 'bg-ink-900 text-white' : 'text-ink-600 hover:bg-ink-100')}>
                  {s === 'ALL' ? '全部' : s === 'reagent' ? '试剂' : '设备'}
                </button>
              ))}
            </div>
          </div>
          {filtered.length === 0 ? (
            <EmptyState title="无匹配报警" hint="当前筛选下没有未处理的报警" />
          ) : (
            <ul>{filtered.map((a, i) => <AlarmRow key={i} a={a} />)}</ul>
          )}
        </Card>
      </div>
    );
  }

  function FilterChip({ active, onClick, disabled, children }) {
    return (
      <button onClick={onClick} disabled={disabled}
        className={cls(
          'inline-flex items-center gap-1 h-7 px-2.5 rounded-md text-xs ring-1 transition-colors',
          active ? 'bg-ink-900 text-white ring-ink-900'
                 : 'bg-white text-ink-700 ring-ink-200 hover:bg-ink-50',
          disabled && 'opacity-40 pointer-events-none'
        )}>
        {children}
      </button>
    );
  }

  Object.assign(window, { Dashboard, AlertsPage, AlarmRow });
})();
