/* X-REAL Stock System — Reservations with calendar/timeline */

const RES_TYPES = [
  { id: "event",       icon: "flag",   label: "Event / งาน",       color: "var(--warn)" },
  { id: "wholesale",   icon: "store",  label: "Wholesale",         color: "var(--info)" },
  { id: "consignment", icon: "consign", label: "Consignment",       color: "var(--purple)" },
];
const RES_TYPE_MAP = Object.fromEntries(RES_TYPES.map(t => [t.id, t]));
const STATUS_META = {
  pending:   { color: "warn",    label: "รอจัดส่ง", icon: "clock" },
  fulfilled: { color: "success", label: "ส่งแล้ว",  icon: "check" },
  cancelled: { color: "default", label: "ยกเลิก",   icon: "x" },
};

function ReservationPage({ products, cats, catMap, locations, stocks, reservations, getTot, getQty, onSave, onFulfill, showToast, askConfirm }) {
  const [view, setView] = useState("list"); // list | new | detail | calendar
  const [selId, setSelId] = useState(null);
  const [statusFilter, setStatusFilter] = useState("pending");
  const [form, setForm] = useState({ title: "", type: "event", customer: "", dueDate: "", note: "", items: [] });
  const baan = locations.find(l => l.name === "บ้าน") || locations.find(l => l.isStorage);

  const getTotalReservedQty = (skuId) =>
    reservations.filter(r => r.status === "pending").flatMap(r => r.items)
      .filter(i => i.skuId === skuId).reduce((a, i) => a + i.qty, 0);
  const getAvailable = (skuId) => {
    const physical = baan ? getQty(skuId, baan.id) : 0;
    return physical - getTotalReservedQty(skuId);
  };
  const getDaysLeft = (dueDate) => {
    if (!dueDate) return null;
    return Math.ceil((new Date(dmyToIso(dueDate) || dueDate) - new Date()) / 86400000);
  };

  const filtered = reservations.filter(r => statusFilter === "all" || r.status === statusFilter)
    .sort((a, b) => {
      if (!a.dueDate && !b.dueDate) return 0;
      if (!a.dueDate) return 1; if (!b.dueDate) return -1;
      return new Date(dmyToIso(a.dueDate) || a.dueDate) - new Date(dmyToIso(b.dueDate) || b.dueDate);
    });

  const counts = {
    all: reservations.length,
    pending: reservations.filter(r => r.status === "pending").length,
    fulfilled: reservations.filter(r => r.status === "fulfilled").length,
    cancelled: reservations.filter(r => r.status === "cancelled").length,
  };

  const addItem = () => setForm(f => ({ ...f, items: [...f.items, { id: uid(), skuId: "", qty: "" }] }));
  const updateItem = (id, field, val) => setForm(f => ({ ...f, items: f.items.map(i => i.id === id ? { ...i, [field]: val } : i) }));
  const removeItem = (id) => setForm(f => ({ ...f, items: f.items.filter(i => i.id !== id) }));

  const saveNew = () => {
    if (!form.title.trim()) return showToast("กรอกชื่อ Reservation", "err");
    const validItems = form.items.filter(i => i.skuId && parseInt(i.qty) > 0);
    if (!validItems.length) return showToast("เพิ่มสินค้าอย่างน้อย 1 รายการ", "err");
    const newRes = {
      id: uid(), title: form.title.trim(), type: form.type,
      customer: form.customer.trim(), dueDate: form.dueDate,
      note: form.note.trim(), status: "pending",
      items: validItems.map(i => ({ skuId: i.skuId, qty: parseInt(i.qty) })),
      createdAt: new Date().toISOString(),
    };
    onSave([newRes, ...reservations]);
    setForm({ title: "", type: "event", customer: "", dueDate: "", note: "", items: [] });
    setView("list");
    showToast(`✓ สร้าง Reservation "${newRes.title}"`);
  };
  const cancelRes = (id) => {
    const r = reservations.find(x => x.id === id);
    askConfirm(`ยกเลิก "${r.title}"?`, "Reservation จะถูกยกเลิกและ stock จะพร้อมใช้งาน", () => {
      onSave(reservations.map(x => x.id === id ? { ...x, status: "cancelled", cancelledAt: new Date().toISOString() } : x));
      showToast("ยกเลิก Reservation แล้ว");
      if (selId === id) { setView("list"); setSelId(null); }
    });
  };
  const fulfillRes = (id) => {
    const r = reservations.find(x => x.id === id);
    askConfirm(`Fulfill "${r.title}"?`, "จะตัดสต็อคจากคลังบ้านตาม FIFO ทันที", () => {
      onFulfill(id);
      if (selId === id) { setView("list"); setSelId(null); }
    });
  };

  const selRes = reservations.find(r => r.id === selId);

  return (
    <div >
      {/* New form */}
      {view === "new" && (
        <div style={{ maxWidth: 720 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
            <Btn variant="ghost" icon="chevron-left" size="sm" onClick={() => setView("list")}>กลับ</Btn>
            <div style={{ fontWeight: 700, fontSize: 16 }}>สร้าง Reservation ใหม่</div>
          </div>
          <Card style={{ marginBottom: 14 }}>
            <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 12, marginBottom: 12 }}>
              <FG label="ชื่องาน / Order"><input className="xr-input" value={form.title} onChange={e => setForm(f => ({ ...f, title: e.target.value }))} placeholder="เช่น Hyrox Bangkok Mar 2026"/></FG>
              <FG label="วันที่ต้องส่ง">
                <DateInput value={dmyToIso(form.dueDate) || form.dueDate} onChange={v => setForm(f => ({ ...f, dueDate: isoToDmy(v) || v }))}/>
              </FG>
            </div>
            <FG label="ประเภท" style={{ marginBottom: 12 }}>
              <div style={{ display: "flex", gap: 8 }}>
                {RES_TYPES.map(t => (
                  <button key={t.id} onClick={() => setForm(f => ({ ...f, type: t.id }))} className="xr-card xr-clickable" style={{
                    flex: 1, padding: "10px 14px", textAlign: "center",
                    border: `1.5px solid ${form.type === t.id ? t.color : "var(--border)"}`,
                    background: form.type === t.id ? `color-mix(in oklab, ${t.color} 8%, transparent)` : undefined,
                  }}>
                    <Icon name={t.icon} size={18} style={{ color: t.color }}/>
                    <div style={{ fontSize: 12, fontWeight: 600, color: form.type === t.id ? t.color : "var(--text-1)", marginTop: 4 }}>{t.label}</div>
                  </button>
                ))}
              </div>
            </FG>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              <FG label="ลูกค้า / งาน"><input className="xr-input" value={form.customer} onChange={e => setForm(f => ({ ...f, customer: e.target.value }))} placeholder="เช่น Hyrox TH"/></FG>
              <FG label="หมายเหตุ"><input className="xr-input" value={form.note} onChange={e => setForm(f => ({ ...f, note: e.target.value }))} placeholder="รายละเอียดเพิ่มเติม"/></FG>
            </div>
          </Card>

          <Card style={{ marginBottom: 14 }}>
            <div style={{ fontWeight: 700, marginBottom: 12, fontSize: 13 }}>รายการสินค้าที่จอง</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 8, marginBottom: 8 }}>
              {form.items.map(item => {
                const p = products.find(x => x.id === item.skuId);
                const avail = item.skuId ? getAvailable(item.skuId) : 0;
                const qty = parseInt(item.qty) || 0;
                const over = qty > 0 && avail < qty;
                return (
                  <div key={item.id} style={{
                    padding: 10, background: "var(--surface-2)", borderRadius: "var(--r-md)",
                    display: "grid", gridTemplateColumns: "minmax(0,2fr) 110px 36px", gap: 8, alignItems: "center",
                  }}>
                    <div>
                      <select className="xr-select" value={item.skuId} onChange={e => updateItem(item.id, "skuId", e.target.value)}>
                        <option value="">— เลือกสินค้า —</option>
                        {products.filter(p => p.active !== false).map(p => <option key={p.id} value={p.id}>{p.sku} — {p.name}</option>)}
                      </select>
                      {item.skuId && (
                        <div style={{ fontSize: 11, marginTop: 4, color: over ? "var(--danger)" : "var(--text-3)" }}>
                          Available (บ้าน − reserved): <strong style={{ color: avail > 0 ? "var(--success)" : "var(--danger)" }}>{avail}</strong>
                          {p && <span style={{ color: "var(--text-3)" }}> {p.unit}</span>}
                          {over && <span style={{ color: "var(--danger)", marginLeft: 6 }}>⚠ ไม่พอ</span>}
                        </div>
                      )}
                    </div>
                    <input type="number" min="1" value={item.qty} onChange={e => updateItem(item.id, "qty", e.target.value)}
                      className="xr-input" placeholder="จำนวน" style={{
                        textAlign: "center", fontWeight: 700,
                        borderColor: over ? "var(--danger-border)" : undefined,
                      }}/>
                    <button onClick={() => removeItem(item.id)} className="xr-btn xr-btn--icon xr-btn--danger-soft">
                      <Icon name="x" size={14}/>
                    </button>
                  </div>
                );
              })}
            </div>
            <button onClick={addItem} className="xr-btn xr-btn--soft" style={{ width: "100%" }}>
              <Icon name="plus" size={15}/>เพิ่มสินค้า
            </button>
          </Card>

          <div style={{ display: "flex", gap: 10 }}>
            <Btn variant="accent" icon="check" onClick={saveNew} full>สร้าง Reservation</Btn>
            <Btn variant="ghost" onClick={() => setView("list")}>ยกเลิก</Btn>
          </div>
        </div>
      )}

      {/* Detail view */}
      {view === "detail" && selRes && (
        <div style={{ maxWidth: 720 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
            <Btn variant="ghost" icon="chevron-left" size="sm" onClick={() => { setView("list"); setSelId(null); }}>กลับ</Btn>
          </div>
          <ReservationDetailCard res={selRes} products={products} getAvailable={getAvailable}
            getDaysLeft={getDaysLeft} onFulfill={() => fulfillRes(selRes.id)} onCancel={() => cancelRes(selRes.id)}/>
        </div>
      )}

      {/* List view */}
      {view === "list" && (
        <div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 10, marginBottom: 16 }}>
            <StatCard label="รอจัดส่ง" value={counts.pending} icon="clock" accent="warn" onClick={() => setStatusFilter("pending")}/>
            <StatCard label="ส่งแล้ว" value={counts.fulfilled} icon="check" accent="success" onClick={() => setStatusFilter("fulfilled")}/>
            <StatCard label="ยกเลิก" value={counts.cancelled} icon="x" onClick={() => setStatusFilter("cancelled")}/>
            <StatCard label="ทั้งหมด" value={counts.all} icon="reserve" accent="accent" onClick={() => setStatusFilter("all")}/>
          </div>

          <div style={{ display: "flex", gap: 8, marginBottom: 14, alignItems: "center", flexWrap: "wrap" }}>
            <Segmented options={[
              { value: "list", label: "List", icon: "list" },
              { value: "calendar", label: "Calendar", icon: "calendar" },
            ]} value={view === "calendar" ? "calendar" : "list"} onChange={v => setView(v)}/>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
              {["pending", "fulfilled", "cancelled", "all"].map(s => (
                <button key={s} onClick={() => setStatusFilter(s)} className="xr-btn xr-btn--sm" style={{
                  background: statusFilter === s ? "var(--accent)" : undefined,
                  color: statusFilter === s ? "#fff" : undefined,
                  borderColor: statusFilter === s ? "transparent" : undefined,
                }}>{s === "all" ? "ทั้งหมด" : STATUS_META[s]?.label}</button>
              ))}
            </div>
            <Btn variant="accent" icon="plus" onClick={() => setView("new")} style={{ marginLeft: "auto" }}>สร้าง Reservation</Btn>
          </div>

          {filtered.length === 0 ? (
            <EmptyState icon="reserve" title="ยังไม่มี Reservation" hint="กดปุ่ม “สร้าง Reservation” เพื่อเริ่มต้น"/>
          ) : (
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {filtered.map(r => (
                <ReservationCard key={r.id} r={r} products={products} getAvailable={getAvailable} getDaysLeft={getDaysLeft}
                  onClick={() => { setSelId(r.id); setView("detail"); }}
                  onFulfill={() => fulfillRes(r.id)} onCancel={() => cancelRes(r.id)}/>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Calendar/timeline view */}
      {view === "calendar" && (
        <ReservationCalendar
          reservations={reservations.filter(r => r.status === "pending")}
          products={products}
          getAvailable={getAvailable} getDaysLeft={getDaysLeft}
          onSelect={(id) => { setSelId(id); setView("detail"); }}
          onBack={() => setView("list")}/>
      )}
    </div>
  );
}

function ReservationCard({ r, products, getAvailable, getDaysLeft, onClick, onFulfill, onCancel }) {
  const type = RES_TYPE_MAP[r.type] || RES_TYPES[0];
  const st = STATUS_META[r.status];
  const daysLeft = getDaysLeft(r.dueDate);
  const totalItems = r.items.reduce((a, i) => a + i.qty, 0);
  const hasStockIssue = r.status === "pending" && r.items.some(i => getAvailable(i.skuId) < i.qty);
  return (
    <div onClick={onClick} className="xr-card xr-clickable" style={{
      padding: "14px 18px", display: "flex", alignItems: "center", gap: 14,
      border: hasStockIssue ? "1px solid var(--danger-border)" : undefined,
    }}>
      <div style={{
        width: 44, height: 44, borderRadius: "var(--r-md)",
        background: `color-mix(in oklab, ${type.color} 14%, transparent)`,
        color: type.color,
        display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
      }}>
        <Icon name={type.icon} size={20}/>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 4 }}>{r.title}</div>
        <div style={{ display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
          <Pill variant={st.color} icon={st.icon}>{st.label}</Pill>
          <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>{type.label}</span>
          {r.customer && <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>· {r.customer}</span>}
          {hasStockIssue && <Pill variant="danger" icon="alert">สต็อคไม่พอ</Pill>}
        </div>
      </div>
      <div style={{ textAlign: "right", flexShrink: 0 }} className="xr-hide-mobile">
        {r.dueDate && (
          <div style={{
            fontSize: 13, fontWeight: 600,
            color: daysLeft !== null && daysLeft <= 3 ? "var(--danger)" : daysLeft !== null && daysLeft <= 7 ? "var(--warn)" : "var(--text-1)",
          }}>
            <Icon name="calendar" size={12} style={{ marginRight: 4, verticalAlign: -1 }}/>{r.dueDate}
          </div>
        )}
        {daysLeft !== null && (
          <div style={{ fontSize: 11, color: "var(--text-3)" }}>
            {daysLeft < 0 ? `เลย ${Math.abs(daysLeft)} วัน` : daysLeft === 0 ? "วันนี้" : `อีก ${daysLeft} วัน`}
          </div>
        )}
        <div style={{ fontSize: 11.5, color: "var(--text-3)", marginTop: 2 }}>{r.items.length} SKU · {totalItems} ชิ้น</div>
      </div>
      {r.status === "pending" && (
        <div style={{ display: "flex", gap: 6 }} onClick={e => e.stopPropagation()} className="xr-hide-mobile">
          <Btn variant="accent" size="sm" icon="check" onClick={onFulfill}>Fulfill</Btn>
          <Btn variant="danger-soft" size="sm" icon="x" onClick={onCancel}/>
        </div>
      )}
    </div>
  );
}

function ReservationDetailCard({ res, products, getAvailable, getDaysLeft, onFulfill, onCancel }) {
  const type = RES_TYPE_MAP[res.type] || RES_TYPES[0];
  const st = STATUS_META[res.status];
  const daysLeft = getDaysLeft(res.dueDate);
  return (
    <Card>
      <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 16, gap: 12, flexWrap: "wrap" }}>
        <div style={{ minWidth: 0, flex: 1 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
            <Icon name={type.icon} size={22} style={{ color: type.color }}/>
            <div style={{ fontSize: 17, fontWeight: 800 }}>{res.title}</div>
          </div>
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
            <Pill variant={st.color} icon={st.icon}>{st.label}</Pill>
            <Pill variant="info">{type.label}</Pill>
            {res.dueDate && (
              <Pill variant={daysLeft < 0 ? "danger" : daysLeft <= 7 ? "warn" : "default"} icon="calendar">
                {res.dueDate} {daysLeft !== null && `(${daysLeft < 0 ? `เลย ${Math.abs(daysLeft)} วัน` : daysLeft === 0 ? "วันนี้" : `อีก ${daysLeft} วัน`})`}
              </Pill>
            )}
          </div>
        </div>
        {res.status === "pending" && (
          <div style={{ display: "flex", gap: 8 }}>
            <Btn variant="accent" icon="check" onClick={onFulfill}>Fulfill</Btn>
            <Btn variant="danger-soft" icon="x" onClick={onCancel}>ยกเลิก</Btn>
          </div>
        )}
      </div>
      {res.customer && <div style={{ fontSize: 13, color: "var(--text-2)", marginBottom: 6 }}><Icon name="user" size={13} style={{ verticalAlign: -2, marginRight: 4 }}/>{res.customer}</div>}
      {res.note && <div style={{ fontSize: 13, color: "var(--text-2)", marginBottom: 14 }}><Icon name="edit" size={13} style={{ verticalAlign: -2, marginRight: 4 }}/>{res.note}</div>}
      <div style={{ borderRadius: "var(--r-md)", overflow: "hidden", border: "1px solid var(--border)" }}>
        <table className="xr-table">
          <thead><tr><th>SKU</th><th>ชื่อสินค้า</th><th style={{ textAlign: "right" }}>จอง</th>
            {res.status === "pending" && <th style={{ textAlign: "right" }}>Available</th>}
            {res.status === "pending" && <th>สถานะ</th>}
          </tr></thead>
          <tbody>
            {res.items.map((item, i) => {
              const p = products.find(x => x.id === item.skuId);
              const avail = getAvailable(item.skuId);
              const ok = avail >= item.qty;
              return (
                <tr key={i}>
                  <td><SkuBadge sku={p?.sku || "—"}/></td>
                  <td>{p?.name || "—"}</td>
                  <td style={{ textAlign: "right", fontWeight: 700, fontVariantNumeric: "tabular-nums" }}>{item.qty} <span style={{ color: "var(--text-3)", fontWeight: 400, fontSize: 11 }}>{p?.unit}</span></td>
                  {res.status === "pending" && <td style={{ textAlign: "right", fontWeight: 700, color: ok ? "var(--success)" : "var(--danger)", fontVariantNumeric: "tabular-nums" }}>{avail}</td>}
                  {res.status === "pending" && <td><Pill variant={ok ? "success" : "danger"}>{ok ? "พอ" : "ไม่พอ"}</Pill></td>}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </Card>
  );
}

// ─── CALENDAR / TIMELINE VIEW ─────────────────────────────────────────
function ReservationCalendar({ reservations, products, getAvailable, getDaysLeft, onSelect, onBack }) {
  const [refMonth, setRefMonth] = useState(() => {
    const d = new Date(); return { y: d.getFullYear(), m: d.getMonth() };
  });
  const shift = (delta) => {
    let { y, m } = refMonth; m += delta;
    if (m < 0) { y -= 1; m = 11; } else if (m > 11) { y += 1; m = 0; }
    setRefMonth({ y, m });
  };
  // Build month grid
  const first = new Date(refMonth.y, refMonth.m, 1);
  const startDay = (first.getDay() + 6) % 7; // monday = 0
  const daysInMonth = new Date(refMonth.y, refMonth.m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < startDay; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);
  while (cells.length % 7) cells.push(null);

  const byDate = {};
  reservations.forEach(r => {
    const iso = dmyToIso(r.dueDate) || r.dueDate;
    if (!iso) return;
    const d = new Date(iso);
    if (d.getFullYear() === refMonth.y && d.getMonth() === refMonth.m) {
      const key = d.getDate();
      (byDate[key] = byDate[key] || []).push(r);
    }
  });

  const monthLabel = `${["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"][refMonth.m]} ${refMonth.y}`;
  const today = new Date();
  const isCurrentMonth = today.getFullYear() === refMonth.y && today.getMonth() === refMonth.m;

  // Upcoming list (next 30 days)
  const upcoming = reservations
    .filter(r => {
      const dl = getDaysLeft(r.dueDate);
      return dl !== null && dl >= 0 && dl <= 30;
    })
    .sort((a, b) => getDaysLeft(a.dueDate) - getDaysLeft(b.dueDate));

  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14, flexWrap: "wrap", gap: 10 }}>
        <Segmented options={[
          { value: "list", label: "List", icon: "list" },
          { value: "calendar", label: "Calendar", icon: "calendar" },
        ]} value="calendar" onChange={v => v === "list" && onBack()}/>
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <Btn variant="ghost" icon="chevron-left" size="sm" onClick={() => shift(-1)}/>
          <div style={{ fontWeight: 700, minWidth: 160, textAlign: "center" }}>{monthLabel}</div>
          <Btn variant="ghost" icon="chevron-right" size="sm" onClick={() => shift(1)}/>
        </div>
      </div>

      <Card padded={false} style={{ marginBottom: 14 }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", borderBottom: "1px solid var(--border)" }}>
          {["จ.", "อ.", "พ.", "พฤ.", "ศ.", "ส.", "อา."].map(d => (
            <div key={d} style={{
              padding: "10px 6px", textAlign: "center",
              fontSize: 11, fontWeight: 700, color: "var(--text-3)",
              textTransform: "uppercase", letterSpacing: .6,
              background: "var(--surface-2)",
            }}>{d}</div>
          ))}
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)" }}>
          {cells.map((d, i) => {
            const items = d ? byDate[d] || [] : [];
            const isToday = isCurrentMonth && today.getDate() === d;
            return (
              <div key={i} style={{
                minHeight: 96, padding: 6,
                borderRight: i % 7 !== 6 ? "1px solid var(--border-subtle)" : undefined,
                borderBottom: "1px solid var(--border-subtle)",
                background: isToday ? "var(--accent-subtle-2)" : undefined,
                position: "relative",
              }}>
                {d && (
                  <>
                    <div style={{
                      fontSize: 11, fontWeight: 700, marginBottom: 4,
                      color: isToday ? "var(--accent-hover)" : "var(--text-2)",
                      display: "inline-flex", alignItems: "center", justifyContent: "center",
                      width: 20, height: 20, borderRadius: 999,
                      background: isToday ? "var(--accent)" : "transparent",
                      ...(isToday ? { color: "#fff" } : {}),
                    }}>{d}</div>
                    <div style={{ display: "flex", flexDirection: "column", gap: 2 }}>
                      {items.slice(0, 3).map(r => {
                        const type = RES_TYPE_MAP[r.type] || RES_TYPES[0];
                        const hasIssue = r.items.some(i => getAvailable(i.skuId) < i.qty);
                        return (
                          <button key={r.id} onClick={() => onSelect(r.id)} style={{
                            display: "flex", alignItems: "center", gap: 4,
                            fontSize: 10.5, fontWeight: 600, padding: "2px 5px",
                            borderRadius: 4, width: "100%", textAlign: "left",
                            background: `color-mix(in oklab, ${type.color} ${hasIssue ? "20%" : "12%"}, transparent)`,
                            color: type.color, overflow: "hidden",
                            border: hasIssue ? "1px solid var(--danger-border)" : undefined,
                          }} title={r.title}>
                            <span style={{ width: 4, height: 4, borderRadius: 999, background: type.color, flexShrink: 0 }}/>
                            <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.title}</span>
                          </button>
                        );
                      })}
                      {items.length > 3 && <div style={{ fontSize: 10, color: "var(--text-3)", padding: "0 4px" }}>+{items.length - 3} อีก…</div>}
                    </div>
                  </>
                )}
              </div>
            );
          })}
        </div>
      </Card>

      {/* Upcoming timeline */}
      <Card padded={false}>
        <div style={{ padding: "14px 18px", borderBottom: "1px solid var(--border-subtle)" }}>
          <div style={{ fontSize: 14, fontWeight: 700 }}>Timeline ใน 30 วันข้างหน้า</div>
          <div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{upcoming.length} reservations</div>
        </div>
        {upcoming.length === 0 ? (
          <div style={{ padding: 20 }}>
            <EmptyState icon="reserve" title="ไม่มี reservation ใน 30 วันข้างหน้า"/>
          </div>
        ) : (
          <div style={{ padding: "12px 18px" }}>
            {upcoming.map(r => {
              const dl = getDaysLeft(r.dueDate);
              const type = RES_TYPE_MAP[r.type] || RES_TYPES[0];
              const hasIssue = r.items.some(i => getAvailable(i.skuId) < i.qty);
              return (
                <div key={r.id} onClick={() => onSelect(r.id)} style={{
                  display: "flex", gap: 14, padding: "10px 0", cursor: "pointer",
                  borderTop: "1px solid var(--border-subtle)",
                }}>
                  <div style={{ minWidth: 56, textAlign: "center", flexShrink: 0 }}>
                    <div style={{
                      fontSize: 22, fontWeight: 800,
                      color: dl <= 3 ? "var(--danger)" : dl <= 7 ? "var(--warn)" : "var(--text-1)",
                      lineHeight: 1,
                    }}>{dl}</div>
                    <div style={{ fontSize: 10, color: "var(--text-3)", marginTop: 2 }}>{dl === 0 ? "วันนี้" : "วัน"}</div>
                  </div>
                  <div style={{ width: 2, background: type.color, borderRadius: 999 }}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 700, marginBottom: 3 }}>{r.title}</div>
                    <div style={{ display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
                      <Pill variant="default">{type.label}</Pill>
                      <span style={{ fontSize: 11, color: "var(--text-3)" }}>📅 {r.dueDate}</span>
                      <span style={{ fontSize: 11, color: "var(--text-3)" }}>· {r.items.length} SKU</span>
                      {hasIssue && <Pill variant="danger" icon="alert">สต็อคไม่พอ</Pill>}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </Card>
    </div>
  );
}

Object.assign(window, { ReservationPage });
