// App.jsx — main packing management app
// React components share scope via window globals (different <script> tags)

const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ────────────────────────────────────────────────────────────
// helpers
// ────────────────────────────────────────────────────────────
const THAI_DAYS = ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'];
const THAI_MONTHS = ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.','ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'];

function fmtDateLabel(iso) {
  const dt = new Date(iso + 'T00:00:00');
  const today = new Date(); today.setHours(0,0,0,0);
  const diff = Math.round((dt - today) / (1000*60*60*24));
  const dayName = THAI_DAYS[dt.getDay()];
  const datePart = `${dt.getDate()} ${THAI_MONTHS[dt.getMonth()]} ${(dt.getFullYear()+543) % 100}`;
  if (diff === 0) return { hero: 'วันนี้', sub: `${dayName} ${datePart}`, diff };
  if (diff === -1) return { hero: 'เมื่อวาน', sub: `${dayName} ${datePart}`, diff };
  if (diff === 1) return { hero: 'พรุ่งนี้', sub: `${dayName} ${datePart}`, diff };
  return { hero: `${dayName} ${datePart}`, sub: diff < 0 ? `${Math.abs(diff)} วันก่อน` : `อีก ${diff} วัน`, diff };
}

function relTime(ts) {
  const diff = Date.now() - ts;
  const m = Math.round(diff / (1000*60));
  if (m < 1) return 'เมื่อกี้';
  if (m < 60) return `${m} นาทีก่อน`;
  const h = Math.round(m / 60);
  if (h < 24) return `${h} ชม.ก่อน`;
  const d = Math.round(h / 24);
  return `${d} วันก่อน`;
}

// ── Supabase data helpers ──────────────────────────────────────
async function fetchOrders() {
  const { data, error } = await window.db
    .from('orders')
    .select('data')
    .order('created_at', { ascending: false });
  if (error) { console.error('fetchOrders:', error); return null; }
  return data.map(r => r.data);
}
function syncOrder(order) {
  // ไม่เซฟรูปภาพลง DB (base64 ใหญ่เกิน → Supabase reject)
  // รูปจะแสดงเฉพาะใน session ปัจจุบันเท่านั้น
  const { images, ...rest } = order;
  window.db.from('orders').upsert({
    id: order.id,
    platform: order.platform,
    date: order.date,
    status: order.status,
    data: { ...rest, images: [] },
  }).then(({ error }) => {
    if (error) console.error('[Supabase] syncOrder failed:', error.message, order.id);
  });
}
// ลบ order ที่ส่งแล้ว/ยกเลิกแล้ว และเก่ากว่า 15 วัน
async function cleanupOldOrders() {
  const cutoff = new Date();
  cutoff.setDate(cutoff.getDate() - 15);
  const cutoffDate = cutoff.toISOString().slice(0, 10);
  await window.db.from('orders')
    .delete()
    .lt('date', cutoffDate)
    .in('status', ['shipped', 'cancelled']);
}

// ────────────────────────────────────────────────────────────
// OrderImageStrip — shows PDF page thumbnails inline in order row
// ────────────────────────────────────────────────────────────
function OrderImageStrip({ images }) {
  const [lightbox, setLightbox] = useState(null);
  if (!images || images.length === 0) return null;
  return (
    <>
      <div className="order-img-strip">
        {images.map((img) => (
          <div key={img.id} className="order-img-thumb-wrap">
            <img
              className="order-img-thumb"
              src={img.dataUrl}
              alt="ใบส่งของ"
              onClick={() => setLightbox(img.dataUrl)}
              title="คลิกดูรูปเต็ม"
            />
          </div>
        ))}
      </div>
      {lightbox && (
        <div className="lightbox-backdrop" onClick={() => setLightbox(null)}>
          <img className="lightbox-img" src={lightbox} onClick={e => e.stopPropagation()} alt="ใบส่งของ" />
          <button className="lightbox-close" onClick={() => setLightbox(null)}>×</button>
        </div>
      )}
    </>
  );
}

// ────────────────────────────────────────────────────────────
// PlatformDot — small colored indicator
// ────────────────────────────────────────────────────────────
function PlatformDot({ platform, size = 8 }) {
  const p = PLATFORMS[platform];
  return (
    <span
      style={{
        display: 'inline-block',
        width: size, height: size, borderRadius: '50%',
        background: p.dot,
        boxShadow: `0 0 0 2px ${p.tint}`,
        flexShrink: 0,
      }}
    />
  );
}

// PlatformBadge — small rounded-square monogram (e.g. "SP", "TT", "LZ")
// Original mark, not a recreation of any brand's actual logo.
function PlatformBadge({ platform, size = 18 }) {
  const p = PLATFORMS[platform];
  return (
    <span
      className="platform-badge"
      style={{
        width: size, height: size,
        background: p.dot,
        fontSize: size * 0.5,
      }}
      aria-label={p.name}
    >
      {p.short}
    </span>
  );
}

const STATUS_COLORS = {
  pending:   { bg: 'oklch(0.94 0.06 60)',  activeBg: 'oklch(0.65 0.16 55)',  text: 'oklch(0.48 0.14 55)',  activeText: '#fff' },
  packed:    { bg: 'oklch(0.93 0.05 245)', activeBg: 'oklch(0.50 0.16 245)', text: 'oklch(0.42 0.14 245)', activeText: '#fff' },
  shipped:   { bg: 'oklch(0.93 0.05 155)', activeBg: 'oklch(0.50 0.14 155)', text: 'oklch(0.40 0.12 155)', activeText: '#fff' },
};

// ────────────────────────────────────────────────────────────
// StatusToggle — pill that cycles pending → packed → shipped
// ────────────────────────────────────────────────────────────
function StatusToggle({ status, onChange }) {
  return (
    <div className="status-toggle">
      {STATUS_FLOW.map((s) => {
        const cfg = STATUSES[s];
        const active = s === status;
        const col = STATUS_COLORS[s];
        return (
          <button
            key={s}
            className={`status-pill ${active ? 'active' : ''}`}
            onClick={() => onChange(s)}
            style={{
              background: active ? col.activeBg : col.bg,
              color: active ? col.activeText : col.text,
              border: 'none',
              fontWeight: active ? 600 : 500,
              boxShadow: active ? `0 1px 3px ${col.activeBg}88` : 'none',
            }}
            title={cfg.label}
          >
            {active && (
              <svg width="11" height="11" viewBox="0 0 12 12" style={{ marginRight: 4 }}>
                {s === 'pending' && <circle cx="6" cy="6" r="3" fill="currentColor" />}
                {s === 'packed' && <path d="M2 6 L5 9 L10 3" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round" />}
                {s === 'shipped' && <path d="M2 6h7M7 3l3 3-3 3" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round" />}
              </svg>
            )}
            {cfg.label}
          </button>
        );
      })}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// NoteIndicator — shows tag icons + note preview in red
// ────────────────────────────────────────────────────────────
function NoteIndicator({ tags, hasNote, note }) {
  const tagObjs = tags.map(t => NOTE_TAGS.find(n => n.id === t)).filter(Boolean);
  if (tagObjs.length === 0 && !hasNote) return null;
  return (
    <div className="note-indicator">
      {tagObjs.map(t => (
        <span key={t.id} className="tag-chip" style={{ color: t.color, borderColor: t.color }} title={t.label}>
          <span className="tag-icon">{t.icon}</span>
          <span className="tag-label">{t.label}</span>
        </span>
      ))}
      {hasNote && (
        <span className="tag-chip note-chip" title="มีโน้ต">
          <span className="tag-icon">✎</span>
          <span className="tag-label">มีโน้ต</span>
        </span>
      )}
      {note && note.trim() && (
        <span className="note-preview">{note.trim()}</span>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// OrderRow
// ────────────────────────────────────────────────────────────
function OrderRow({ order, onStatusChange, onOpenNote }) {
  const p = PLATFORMS[order.platform];
  const dim = order.status === 'shipped';
  return (
    <div className={`order-row status-${order.status} ${dim ? 'dim' : ''}`}>
      <div className="order-left">
        <div className="order-platform">
          <PlatformDot platform={order.platform} />
          <span className="platform-name">{p.name}</span>
        </div>
        <div className="order-code">{order.code}</div>
        <div className="order-meta">
          <span>{order.customer}</span>
          <span className="dot-sep">·</span>
          <span>{order.qty} ชิ้น</span>
          <span className="dot-sep">·</span>
          <span>อัปเดต {relTime(order.updated)}</span>
        </div>
        {(order.tags.length > 0 || order.note) && (
          <NoteIndicator tags={order.tags} hasNote={!!order.note} note={order.note} />
        )}
        {order.images && order.images.length > 0 && (
          <OrderImageStrip images={order.images} />
        )}
      </div>
      <div className="order-right">
        <button className="note-btn" onClick={() => onOpenNote(order)} title="เปิดโน้ต">
          <svg width="14" height="14" viewBox="0 0 16 16">
            <path d="M3 3h7l3 3v7a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" fill="none" stroke="currentColor" strokeWidth="1.2" />
            <path d="M5 7h6M5 9.5h6M5 12h4" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />
          </svg>
          โน้ต
          {(order.note || order.tags.length > 0) && <span className="note-badge" />}
        </button>
        {order.status !== 'cancelled' ? (
          <>
            <StatusToggle status={order.status} onChange={(s) => onStatusChange(order.id, s)} />
            <button
              className="cancel-btn"
              onClick={() => { if (window.confirm('ยืนยันยกเลิกคำสั่งซื้อนี้?')) onStatusChange(order.id, 'cancelled'); }}
              title="ยกเลิกบิล"
            >
              <svg width="12" height="12" viewBox="0 0 12 12">
                <path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
              </svg>
              ยกเลิก
            </button>
          </>
        ) : (
          <button
            className="restore-btn"
            onClick={() => onStatusChange(order.id, 'pending')}
            title="เริ่มใหม่"
          >
            เริ่มใหม่
          </button>
        )}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// DayGroup
// ────────────────────────────────────────────────────────────
function DayGroup({ date, orders, expanded, onToggle, onStatusChange, onOpenNote, platformFilter }) {
  const label = fmtDateLabel(date);
  const filtered = platformFilter === 'all' ? orders : orders.filter(o => o.platform === platformFilter);

  // counts per platform
  const counts = useMemo(() => {
    const c = { shopee: 0, tiktok: 0, lazada: 0, total: 0, pending: 0, packed: 0, shipped: 0, qty: 0 };
    for (const o of filtered) {
      c[o.platform]++;
      c.total++;
      c[o.status]++;
      c.qty += o.qty;
    }
    return c;
  }, [filtered]);

  // group by platform within the day
  const byPlatform = useMemo(() => {
    const g = { shopee: [], tiktok: [], lazada: [] };
    for (const o of filtered) g[o.platform].push(o);
    return g;
  }, [filtered]);

  const isToday = label.diff === 0;
  const overdueCount = counts.pending + counts.packed;
  const hasOverdue = overdueCount > 0;

  return (
    <section className={`day-group ${expanded ? 'open' : 'closed'} ${isToday ? 'today' : ''}`}>
      <header className="day-header" onClick={onToggle}>
        <div className="day-header-left">
          <button className="caret" tabIndex="-1">
            <svg width="10" height="10" viewBox="0 0 10 10" style={{ transform: expanded ? 'rotate(90deg)' : 'rotate(0)', transition: 'transform .2s' }}>
              <path d="M3 2 L7 5 L3 8" stroke="currentColor" strokeWidth="1.4" fill="none" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </button>
          <div className="day-title">
            <div className="day-hero">
              {label.hero}
              {isToday && <span className="today-tag">วันนี้</span>}
              {!isToday && hasOverdue && label.diff < 0 && <span className="overdue-tag">ค้าง {overdueCount}</span>}
            </div>
            <div className="day-sub">{label.sub}</div>
          </div>
        </div>
        <div className="day-header-right">
          <div className="counter-group">
            <div className="counter big">
              <span className="counter-num">{counts.total}</span>
              <span className="counter-lbl">คำสั่งซื้อ</span>
            </div>
          </div>
          <div className="platform-counts">
            {(['shopee','tiktok','lazada']).map(pid => (
              <div key={pid} className="pc-item" style={{ opacity: counts[pid] ? 1 : 0.4 }}>
                <PlatformBadge platform={pid} size={18} />
                <span className="pc-name">{PLATFORMS[pid].name}</span>
                <span className="pc-num">{counts[pid]}</span>
              </div>
            ))}
          </div>
          <div className="status-bar" title={`รอแพ็ค ${counts.pending} · แพ็ค ${counts.packed} · ส่ง ${counts.shipped}`}>
            {counts.total > 0 && (
              <>
                <div className="sb-seg sb-pending" style={{ flex: counts.pending }} />
                <div className="sb-seg sb-packed" style={{ flex: counts.packed }} />
                <div className="sb-seg sb-shipped" style={{ flex: counts.shipped }} />
              </>
            )}
          </div>
        </div>
      </header>
      {expanded && (
        <div className="day-body">
          {counts.total === 0 ? (
            <div className="empty-day">ไม่มีคำสั่งซื้อในวันนี้</div>
          ) : (
            ['shopee','tiktok','lazada'].map(pid => {
              const list = byPlatform[pid];
              if (list.length === 0) return null;
              return (
                <div key={pid} className="platform-group">
                  <div className="pg-header">
                    <PlatformBadge platform={pid} size={22} />
                    <span className="pg-name">{PLATFORMS[pid].name}</span>
                    <span className="pg-count">{list.length} คำสั่งซื้อ · {list.reduce((s,o)=>s+o.qty,0)} ชิ้น</span>
                  </div>
                  <div className="orders-list">
                    {list.map(o => (
                      <OrderRow key={o.id} order={o} onStatusChange={onStatusChange} onOpenNote={onOpenNote} />
                    ))}
                  </div>
                </div>
              );
            })
          )}
        </div>
      )}
    </section>
  );
}

// ────────────────────────────────────────────────────────────
// NoteModal
// ────────────────────────────────────────────────────────────
function NoteModal({ order, onClose, onSave }) {
  const [note, setNote] = useState(order.note || '');
  const [tags, setTags] = useState([...order.tags]);
  const txtRef = useRef(null);

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    setTimeout(() => txtRef.current?.focus(), 50);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const toggleTag = (id) => {
    setTags(tags.includes(id) ? tags.filter(t => t !== id) : [...tags, id]);
  };

  const save = () => { onSave(order.id, { note: note.trim(), tags }); onClose(); };

  const p = PLATFORMS[order.platform];

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <header className="modal-header">
          <div>
            <div className="modal-eyebrow">
              <PlatformDot platform={order.platform} />
              <span>{p.name}</span>
              <span className="dot-sep">·</span>
              <span>{order.customer}</span>
            </div>
            <h2 className="modal-title">{order.code}</h2>
          </div>
          <button className="close-btn" onClick={onClose} aria-label="ปิด">×</button>
        </header>

        <div className="modal-body">
          <div className="modal-section">
            <label className="modal-label">สัญลักษณ์งานพิเศษ</label>
            <div className="tag-grid">
              {NOTE_TAGS.map(t => {
                const active = tags.includes(t.id);
                return (
                  <button
                    key={t.id}
                    className={`tag-option ${active ? 'active' : ''}`}
                    style={active ? { '--tag-c': t.color } : undefined}
                    onClick={() => toggleTag(t.id)}
                  >
                    <span className="tag-option-icon">{t.icon}</span>
                    <span>{t.label}</span>
                  </button>
                );
              })}
            </div>
          </div>

          <div className="modal-section">
            <label className="modal-label" htmlFor="note-text">โน้ตเพิ่มเติม</label>
            <textarea
              ref={txtRef}
              id="note-text"
              className="note-text"
              placeholder="เช่น ลูกค้าขอห่อพิเศษ / ของแถม / รายละเอียดที่ต้องระวัง…"
              value={note}
              onChange={(e) => setNote(e.target.value)}
            />
          </div>
        </div>

        <footer className="modal-footer">
          <button className="btn ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn primary" onClick={save}>บันทึก</button>
        </footer>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Top summary bar
// ────────────────────────────────────────────────────────────
function SummaryBar({ orders, platformFilter, setPlatformFilter, statusFilter, setStatusFilter, search, setSearch }) {
  const todayDate = d => d === new Date().toISOString().slice(0,10);
  const today = useMemo(() => {
    const t = new Date().toISOString().slice(0,10);
    return orders.filter(o => o.date === t);
  }, [orders]);

  const stats = useMemo(() => {
    const s = { total: today.length, pending: 0, packed: 0, shipped: 0, qty: 0,
                shopee: 0, tiktok: 0, lazada: 0 };
    for (const o of today) { s[o.status]++; s.qty += o.qty; s[o.platform]++; }
    return s;
  }, [today]);

  // backlog: pending from past days
  const backlog = useMemo(() => {
    const t = new Date().toISOString().slice(0,10);
    return orders.filter(o => o.date < t && o.status !== 'shipped').length;
  }, [orders]);

  return (
    <div className="summary-bar">
      <div className="summary-left">
        <div className="brand">
          <div className="brand-mark">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
              <path d="M4 8 L12 4 L20 8 L20 17 L12 21 L4 17 Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
              <path d="M4 8 L12 12 L20 8" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
              <path d="M12 12 L12 21" stroke="currentColor" strokeWidth="1.6" />
            </svg>
          </div>
          <div className="brand-text">
            <div className="brand-title">ระบบจัดการแพ็คสินค้า</div>
            <div className="brand-sub">3 แพลตฟอร์ม · จัดกลุ่มรายวัน</div>
          </div>
        </div>
      </div>

      <div className="summary-stats">
        <Stat label="ออเดอร์วันนี้" value={stats.total} sub={`${stats.qty} ชิ้น`} />
        <Stat label="รอแพ็ค" value={stats.pending} accent="oklch(0.55 0.02 70)" />
        <Stat label="แพ็คเสร็จ" value={stats.packed} accent="oklch(0.55 0.12 200)" />
        <Stat label="ส่งออกแล้ว" value={stats.shipped} accent="oklch(0.58 0.13 160)" />
        <Stat label="ค้างจากเมื่อวาน" value={backlog} accent={backlog ? 'oklch(0.62 0.16 35)' : undefined} alert={backlog > 0} />
      </div>
    </div>
  );
}

function Stat({ label, value, sub, accent, alert }) {
  return (
    <div className={`stat ${alert ? 'alert' : ''}`}>
      <div className="stat-label">{label}</div>
      <div className="stat-value" style={accent ? { color: accent } : undefined}>
        {value}
        {sub && <span className="stat-sub">{sub}</span>}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Filter toolbar
// ────────────────────────────────────────────────────────────
function FilterBar({ platformFilter, setPlatformFilter, statusFilter, setStatusFilter, search, setSearch, hideShipped, setHideShipped, onImport, onScan }) {
  return (
    <div className="filter-bar">
      <div className="filter-group platform-filter">
        <button className={`fb-pill ${platformFilter==='all' ? 'on' : ''}`} onClick={() => setPlatformFilter('all')}>ทั้งหมด</button>
        {Object.values(PLATFORMS).map(p => (
          <button
            key={p.id}
            className={`fb-pill ${platformFilter===p.id ? 'on' : ''}`}
            onClick={() => setPlatformFilter(p.id)}
          >
            <PlatformDot platform={p.id} size={7} />
            {p.name}
          </button>
        ))}
      </div>

      <div className="filter-group">
        <button className={`fb-pill ${statusFilter==='all' ? 'on' : ''}`} onClick={() => setStatusFilter('all')}>ทุกสถานะ</button>
        <button className={`fb-pill ${statusFilter==='pending' ? 'on' : ''}`} onClick={() => setStatusFilter('pending')}>รอแพ็ค</button>
        <button className={`fb-pill ${statusFilter==='packed' ? 'on' : ''}`} onClick={() => setStatusFilter('packed')}>แพ็คเสร็จ</button>
        <button className={`fb-pill ${statusFilter==='shipped' ? 'on' : ''}`} onClick={() => setStatusFilter('shipped')}>ส่งออกแล้ว</button>
      </div>

      <div className="filter-spacer" />

      <label className="hide-shipped">
        <input type="checkbox" checked={hideShipped} onChange={(e) => setHideShipped(e.target.checked)} />
        <span>ซ่อนที่ส่งแล้ว</span>
      </label>

      <div className="search-box">
        <svg width="14" height="14" viewBox="0 0 16 16">
          <circle cx="7" cy="7" r="5" stroke="currentColor" strokeWidth="1.4" fill="none" />
          <path d="M11 11 L14 14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" />
        </svg>
        <input
          type="text"
          placeholder="ค้นหาเลขคำสั่งซื้อ / ลูกค้า"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
      </div>

      <button className="scan-launch-btn" onClick={onScan} title="สแกน Barcode">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
          <path d="M3 7V4a1 1 0 0 1 1-1h3M17 3h3a1 1 0 0 1 1 1v3M21 17v3a1 1 0 0 1-1 1h-3M7 21H4a1 1 0 0 1-1-1v-3" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
          <path d="M6 8v8M9 8v8M12 8v8M15 8v8M18 8v8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
        </svg>
        สแกน
      </button>

      <button className="import-btn" onClick={onImport} title="นำเข้าจาก PDF">
        <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
          <path d="M8 2v8M4 7l4 4 4-4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
          <path d="M3 13h10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
        </svg>
        นำเข้า PDF
      </button>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Main App
// ────────────────────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "regular",
  "accent": "#2A6FDB",
  "showRelativeTime": true,
  "autoCollapseDone": false
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = (window.useTweaks || (() => [TWEAK_DEFAULTS, () => {}]))(TWEAK_DEFAULTS);
  const [orders, setOrders] = useState([]);
  const [dbLoading, setDbLoading] = useState(true);
  const [platformFilter, setPlatformFilter] = useState('all');
  const [statusFilter, setStatusFilter] = useState('all');
  const [hideShipped, setHideShipped] = useState(false);
  const [search, setSearch] = useState('');
  const [openNote, setOpenNote] = useState(null);
  const [showImport, setShowImport] = useState(false);
  const [showScanner, setShowScanner] = useState(false);
  const [expandedDays, setExpandedDays] = useState(() => {
    const t = new Date().toISOString().slice(0,10);
    const yest = (() => { const d = new Date(); d.setDate(d.getDate()-1); return d.toISOString().slice(0,10); })();
    return new Set([t, yest]);
  });

  // Load from Supabase on mount + cleanup orders older than 15 days
  useEffect(() => {
    cleanupOldOrders()
      .then(() => fetchOrders())
      .then(data => {
        if (data === null) console.error('[Supabase] fetchOrders returned null — check connection & RLS');
        setOrders(data || []);
        setDbLoading(false);
      })
      .catch(err => {
        console.error('[Supabase] load error:', err);
        setOrders([]);
        setDbLoading(false);
      });
  }, []);

  // filter
  const filteredOrders = useMemo(() => {
    return orders.filter(o => {
      if (statusFilter !== 'all' && o.status !== statusFilter) return false;
      if (hideShipped && o.status === 'shipped') return false;
      if (search) {
        const q = search.toLowerCase();
        if (!o.code.toLowerCase().includes(q) && !o.customer.toLowerCase().includes(q)) return false;
      }
      return true;
    });
  }, [orders, statusFilter, hideShipped, search]);

  // group by date desc
  const byDate = useMemo(() => {
    const g = {};
    for (const o of filteredOrders) {
      (g[o.date] = g[o.date] || []).push(o);
    }
    const dates = Object.keys(g).sort((a,b) => b.localeCompare(a));
    return dates.map(d => ({ date: d, orders: g[d] }));
  }, [filteredOrders]);

  const updateOrderStatus = useCallback((id, status) => {
    const updated = Date.now();
    setOrders(prev => {
      const next = prev.map(o => o.id === id ? { ...o, status, updated } : o);
      const order = next.find(o => o.id === id);
      if (order) syncOrder(order);
      return next;
    });
  }, []);

  const updateOrderNote = useCallback((id, { note, tags }) => {
    const updated = Date.now();
    setOrders(prev => {
      const next = prev.map(o => o.id === id ? { ...o, note, tags, updated } : o);
      const order = next.find(o => o.id === id);
      if (order) syncOrder(order);
      return next;
    });
  }, []);

  const importOrders = useCallback((newOrders) => {
    setOrders(prev => {
      const existingKeys = new Set(prev.map(o => o.platform + '|' + o.code));
      const fresh = newOrders.filter(o => !existingKeys.has(o.platform + '|' + o.code));
      const dupes = newOrders.length - fresh.length;
      fresh.forEach(o => syncOrder(o));
      if (dupes > 0) alert(`นำเข้าสำเร็จ ${fresh.length} คำสั่งซื้อ (ซ้ำ ${dupes} รายการ ข้ามไป)`);
      return [...fresh, ...prev];
    });
    setExpandedDays(prev => {
      const next = new Set(prev);
      newOrders.forEach(o => next.add(o.date));
      return next;
    });
  }, []);

  const toggleDay = (date) => {
    setExpandedDays(prev => {
      const next = new Set(prev);
      if (next.has(date)) next.delete(date); else next.add(date);
      return next;
    });
  };

  // density class
  const densityClass = `density-${t.density || 'regular'}`;

  if (dbLoading) return (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'center', height:'100vh', color:'var(--ink-3)', fontFamily:'IBM Plex Sans Thai, sans-serif', fontSize:14 }}>
      กำลังโหลดข้อมูล…
    </div>
  );

  return (
    <div className={`app ${densityClass}`} style={{ '--accent': t.accent }}>
      <SummaryBar orders={orders}
        platformFilter={platformFilter} setPlatformFilter={setPlatformFilter}
        statusFilter={statusFilter} setStatusFilter={setStatusFilter}
        search={search} setSearch={setSearch}
      />
      <FilterBar
        platformFilter={platformFilter} setPlatformFilter={setPlatformFilter}
        statusFilter={statusFilter} setStatusFilter={setStatusFilter}
        search={search} setSearch={setSearch}
        hideShipped={hideShipped} setHideShipped={setHideShipped}
        onImport={() => setShowImport(true)}
        onScan={() => setShowScanner(true)}
      />

      {window.SpecialPanel && <window.SpecialPanel />}

      <main className="day-list">
        {byDate.map(({ date, orders }) => (
          <DayGroup
            key={date}
            date={date}
            orders={orders}
            expanded={expandedDays.has(date)}
            onToggle={() => toggleDay(date)}
            onStatusChange={updateOrderStatus}
            onOpenNote={setOpenNote}
            platformFilter={platformFilter}
          />
        ))}
        {byDate.length === 0 && (
          <div className="empty-state">ไม่พบคำสั่งซื้อตามเงื่อนไขที่เลือก</div>
        )}
      </main>

      {showScanner && window.ScannerModal && (
        <window.ScannerModal
          orders={orders}
          onClose={() => setShowScanner(false)}
          onStatusChange={updateOrderStatus}
        />
      )}

      {showImport && window.ImportModal && (
        <window.ImportModal onClose={() => setShowImport(false)} onImport={importOrders} />
      )}

      {openNote && (
        <NoteModal
          order={orders.find(o => o.id === openNote.id)}
          onClose={() => setOpenNote(null)}
          onSave={updateOrderNote}
        />
      )}

      {window.TweaksPanel && (
        <window.TweaksPanel>
          <window.TweakSection label="การแสดงผล" />
          <window.TweakRadio
            label="ความหนาแน่น"
            value={t.density}
            options={[
              { value: 'compact', label: 'แน่น' },
              { value: 'regular', label: 'ปกติ' },
              { value: 'comfy',   label: 'โปร่ง' },
            ]}
            onChange={(v) => setTweak('density', v)}
          />
          <window.TweakColor
            label="สีเน้น"
            value={t.accent}
            options={['#2A6FDB', '#1F8A5B', '#7A5AE0', '#D97757', '#0F172A']}
            onChange={(v) => setTweak('accent', v)}
          />
          <window.TweakToggle
            label="แสดงเวลาแบบสัมพันธ์"
            value={t.showRelativeTime}
            onChange={(v) => setTweak('showRelativeTime', v)}
          />
          <window.TweakSection label="การดำเนินการ" />
          <window.TweakButton
            label="รีเซ็ตข้อมูลตัวอย่าง"
            onClick={async () => {
              if (!window.confirm('ลบข้อมูลทั้งหมดและโหลดตัวอย่าง?')) return;
              await window.db.from('orders').delete().neq('id', '');
              SEED_ORDERS.forEach(o => syncOrder(o));
              setOrders(SEED_ORDERS);
            }}
          />
        </window.TweaksPanel>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
