/* A1 — Orders list. Search, status filter, sort-by-urgency, responsive, empty state.
   Also exports shared bits (TimeLeftPill, StatusBadge, useIsNarrow). */
const Sorders = window.SparkleClassicDesignSystem_7a1470;

function useIsNarrow(bp = 760) {
  const [n, setN] = React.useState(() => (typeof window !== 'undefined' ? window.innerWidth < bp : false));
  React.useEffect(() => {
    const on = () => setN(window.innerWidth < bp);
    window.addEventListener('resize', on); on();
    return () => window.removeEventListener('resize', on);
  }, [bp]);
  return n;
}

function StatusBadge({ status }) {
  const { Badge } = Sorders;
  const s = ASTATUS[status] || ASTATUS.received;
  return <Badge tone={s.tone} dot>{s.label}</Badge>;
}

function TimeLeftPill({ min, big }) {
  const { Icon } = Sorders;
  const tl = fmtTimeLeft(min);
  if (min >= 900) return <span className="spk-muted" style={{ fontSize: big ? 14 : 13 }}>—</span>;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontWeight: 800, fontSize: big ? 14 : 12.5, color: LEVEL_COLOR[tl.level], whiteSpace: 'nowrap' }}>
      <Icon name={tl.icon} size={big ? 16 : 14} aria-hidden="true" />{tl.text}
    </span>
  );
}

const A1_FILTERS = [
  { id: 'all', label: 'All' },
  { id: 'received', label: 'Received' },
  { id: 'art', label: 'Art in progress' },
  { id: 'published', label: 'Published' },
  { id: 'ready', label: 'Ready' },
  { id: 'action', label: 'Action needed' },
  { id: 'refunded', label: 'Refunded' },
];

function StatCard({ label, value, tone }) {
  const { Card } = Sorders;
  return (
    <Card surface="card" padding="md" shadow="block" style={{ flex: 1, minWidth: 130 }}>
      <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 30, color: tone || 'var(--plum-ink)', lineHeight: 1 }}>{value}</div>
      <div className="spk-muted" style={{ fontSize: 13, marginTop: 6 }}>{label}</div>
    </Card>
  );
}

// Avatar pixel sizes, mirroring the design system's .spk-avatar--<size> rules.
const AVATAR_PX = { xs: 28, sm: 40, md: 56, lg: 80, xl: 120 };

// Pet avatar: the real photo while it is kept, then the pixel sprite once the
// game is published (the photo gets auto-deleted), else the initials fallback.
// `photoSrc` lets a caller pass an already-loaded photo data URL to skip a fetch.
function PetAvatar({ order, size = 'sm', shape = 'square', photoSrc }) {
  const { Avatar } = Sorders;
  const [failed, setFailed] = React.useState(false);
  const px = AVATAR_PX[size] || 40;
  const present = order.photo && order.photo.state === 'present';
  let src = null, sprite = false;
  if (present) src = photoSrc || `/api/order?id=${encodeURIComponent(order.id)}&photo=1&img=1`;
  else if (order.sprite && order.sprite.uploaded) { src = `/api/pet?slug=${encodeURIComponent(order.slug)}&asset=sprite`; sprite = true; }
  // Retry whenever the resolved src changes (e.g. a late-loading photoSrc replaces
  // the endpoint URL) so a transient miss doesn't pin us to the initials fallback.
  React.useEffect(() => setFailed(false), [src]);
  if (!src || failed) return <Avatar name={order.petName} shape={shape} size={size} />;
  return (
    <span style={{ width: px, height: px, flex: '0 0 auto', display: 'block', overflow: 'hidden', boxShadow: 'var(--ofx-edges)', background: 'var(--cream)', borderRadius: shape === 'round' ? '50%' : 0 }}>
      {/* sprite is a 3x3 sheet — scale 300% so only the top-left idle frame shows */}
      <img src={src} alt="" loading="lazy" onError={() => setFailed(true)}
        style={sprite
          ? { width: '300%', height: '300%', imageRendering: 'pixelated', display: 'block' }
          : { width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
    </span>
  );
}

function OrdersList({ orders, onOpen }) {
  const { Input, Icon, Avatar } = Sorders;
  const narrow = useIsNarrow();
  const [q, setQ] = React.useState('');
  const [filter, setFilter] = React.useState('all');

  const actionCount = orders.filter((o) => o.status === 'action').length;
  const dueSoon = orders.filter((o) => o.dueInMin < 360 && o.dueInMin > 0 && o.status !== 'ready' && o.status !== 'refunded').length;

  let rows = orders.filter((o) => {
    if (filter !== 'all' && o.status !== filter) return false;
    if (q.trim()) {
      const t = (o.petName + ' ' + o.email + ' ' + o.customer + ' ' + o.id).toLowerCase();
      if (!t.includes(q.trim().toLowerCase())) return false;
    }
    return true;
  });
  rows = rows.slice().sort((a, b) => a.dueInMin - b.dueInMin); // most urgent first

  return (
    <div>
      <div style={{ marginBottom: 16 }}>
        <h1 className="spk-h2" style={{ fontSize: 26, margin: '0 0 4px' }}>Orders</h1>
        <p className="spk-muted" style={{ fontSize: 14, margin: 0 }}>Sorted by most urgent. Newest paid orders rise as their 24-hour window runs down.</p>
      </div>

      <div style={{ display: 'flex', gap: 12, marginBottom: 16, flexWrap: 'wrap' }}>
        <StatCard label="Open orders" value={String(orders.filter((o) => o.status !== 'ready' && o.status !== 'refunded').length)} />
        <StatCard label="Action needed" value={String(actionCount)} tone="var(--warning)" />
        <StatCard label="Due within 6h" value={String(dueSoon)} tone="var(--danger)" />
        <StatCard label="Delivered" value={String(orders.filter((o) => o.status === 'ready').length)} tone="var(--success)" />
      </div>

      {/* controls */}
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center', marginBottom: 14 }}>
        <div style={{ flex: 1, minWidth: 200 }}>
          <Input placeholder="Search by pet name or email…" leftIcon={<Icon name="search" />} aria-label="Search orders" value={q} onChange={(e) => setQ(e.target.value)} />
        </div>
      </div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16 }}>
        {A1_FILTERS.map((f) => (
          <button key={f.id} onClick={() => setFilter(f.id)} aria-pressed={filter === f.id} style={{
            fontFamily: 'var(--font-body)', fontWeight: 800, fontSize: 12.5, cursor: 'pointer', padding: '6px 12px', border: 0,
            boxShadow: 'var(--ofx-edges)', whiteSpace: 'nowrap',
            background: filter === f.id ? 'var(--action)' : 'var(--cream-surface)',
            color: filter === f.id ? 'var(--cream)' : 'var(--plum-ink)',
          }}>{f.label}</button>
        ))}
      </div>

      {/* empty state */}
      {orders.length === 0 ? (
        <EmptyState title="No orders yet." sub="When a customer checks out, their order lands here." />
      ) : rows.length === 0 ? (
        <EmptyState title="No orders match." sub="Try a different filter or search." />
      ) : narrow ? (
        <div style={{ display: 'grid', gap: 12 }}>
          {rows.map((o) => (
            <button key={o.id} onClick={() => onOpen(o)} style={{ textAlign: 'left', background: o.status === 'action' ? 'var(--warning-tint)' : 'var(--white)', border: 0, boxShadow: 'var(--ofx-edges)', padding: 14, cursor: 'pointer' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <PetAvatar order={o} size="md" />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
                    <strong style={{ color: 'var(--plum-ink)', fontSize: 16 }}>{o.petName}</strong>
                    <span style={{ fontWeight: 800, color: 'var(--plum-ink)' }}>{o.amount}</span>
                  </div>
                  <div className="spk-muted" style={{ fontSize: 13 }}>{o.customer} · {o.email}</div>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8, marginTop: 8 }}>
                    <StatusBadge status={o.status} />
                    <TimeLeftPill min={o.dueInMin} />
                  </div>
                </div>
              </div>
            </button>
          ))}
        </div>
      ) : (
        <div style={{ boxShadow: 'var(--ofx-edges)', overflow: 'hidden', background: 'var(--white)' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1.7fr 1.7fr 1.3fr 1fr 1.1fr', gap: 12, padding: '11px 16px', background: 'var(--pink-soft)', borderBottom: '3px solid var(--plum-ink)', fontFamily: 'var(--font-pixel)', fontSize: 9, color: 'var(--plum-ink)' }}>
            <span>HERO / ORDER</span><span>CUSTOMER</span><span>STATUS</span><span>PAID</span><span style={{ textAlign: 'right' }}>TIME LEFT</span>
          </div>
          {rows.map((o, i) => (
            <button key={o.id} onClick={() => onOpen(o)} style={{
              display: 'grid', gridTemplateColumns: '1.7fr 1.7fr 1.3fr 1fr 1.1fr', gap: 12, alignItems: 'center', width: '100%', textAlign: 'left',
              padding: '12px 16px', cursor: 'pointer', border: 'none', fontFamily: 'var(--font-body)',
              background: o.status === 'action' ? 'var(--warning-tint)' : i % 2 ? 'var(--cream-surface)' : 'var(--white)',
              borderBottom: i < rows.length - 1 ? '1px solid var(--border-soft)' : 'none',
            }}>
              <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <PetAvatar order={o} size="sm" />
                <span><strong style={{ color: 'var(--plum-ink)', display: 'block', fontSize: 15 }}>{o.petName}</strong><span style={{ fontFamily: 'var(--font-pixel)', fontSize: 8, color: 'var(--plum-accent)' }}>{o.id} · {o.amount}</span></span>
              </span>
              <span style={{ minWidth: 0 }}><span style={{ color: 'var(--plum-ink)', fontSize: 14, display: 'block' }}>{o.customer}</span><span className="spk-muted" style={{ fontSize: 12.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', display: 'block' }}>{o.email}</span></span>
              <span><StatusBadge status={o.status} /></span>
              <span className="spk-muted" style={{ fontSize: 13 }}>{o.paidAt}</span>
              <span style={{ textAlign: 'right' }}><TimeLeftPill min={o.dueInMin} /></span>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function EmptyState({ title, sub }) {
  const { Icon, Sparkle } = Sorders;
  return (
    <div style={{ textAlign: 'center', padding: '60px 20px', boxShadow: 'var(--ofx-edges)', background: 'var(--cream-surface)' }}>
      <Sparkle size={30} />
      <h2 className="spk-h3" style={{ fontSize: 20, margin: '10px 0 4px' }}>{title}</h2>
      <p className="spk-muted" style={{ fontSize: 14, margin: 0 }}>{sub}</p>
    </div>
  );
}

Object.assign(window, { OrdersList, StatusBadge, TimeLeftPill, useIsNarrow, EmptyState, PetAvatar });
