/* global React, ReactDOM, I, UI, SSSData */
const { useState: useStateApp, useEffect: useEffectApp, useRef: useRefApp } = React;

const NAV = [
{ section: "ภาพรวม" },
{ key: "dashboard", label: "แดชบอร์ด", icon: I.dashboard },
{ section: "งานส่งของ" },
{ key: "daily-delivery", label: "ส่งของประจำวัน", icon: I.truck },
{ section: "การขาย" },
{ key: "quotations", label: "ใบเสนอราคา", icon: I.doc },
{ key: "delivery-notes", label: "ใบส่งสินค้า", icon: I.truck },
{ key: "invoices", label: "ใบส่งสินค้า/ใบแจ้งหนี้", icon: I.invoice },
{ key: "tax-invoices", label: "ใบกำกับภาษี", icon: I.tax },
{ key: "billing-notes", label: "ใบวางบิล", icon: I.receipt },
{ key: "receipts", label: "ใบเสร็จรับเงิน", icon: I.check },
{ section: "การซื้อ" },
{ key: "purchase-orders", label: "ใบสั่งซื้อ", icon: I.buy },
{ key: "expenses", label: "ค่าใช้จ่าย", icon: I.receipt },
{ key: "payment-vouchers", label: "ใบสำคัญจ่าย", icon: I.money },
{ key: "receipt-vouchers", label: "ใบสำคัญรับเงิน", icon: I.receipt },
{ section: "การเงิน" },
{ key: "cash-advances", label: "เงินสด", icon: I.calc },
{ key: "company-cash", label: "บัญชีธนาคาร", icon: I.money },
{ key: "bank-accounts", label: "จัดการบัญชีธนาคาร", icon: I.book },
{ section: "คลังสินค้า" },
{ key: "inventory", label: "สินค้าและสต็อก", icon: I.warehouse },
{ key: "stock-movements", label: "การเคลื่อนไหว", icon: I.move },
{ key: "barcode", label: "บาร์โค้ด", icon: I.barcode },
{ section: "การลงเวลา" },
{ key: "qr-clock", label: "ลงเวลา QR", icon: I.qr },
{ key: "my-work", label: "งานของฉัน", icon: I.briefcase },
{ section: "เงินเดือน" },
{ key: "payroll", label: "คำนวนเงินเดือน", icon: I.payroll },
{ key: "kpi", label: "KPI ประเมินผล", icon: I.sparkle },
{ section: "บัญชี" },
{ key: "cashbook", label: "รายรับรายจ่าย", icon: I.money },
{ key: "accounting", label: "บัญชีและภาษี", icon: I.book },
{ key: "wht-certs", label: "หนังสือรับรอง 50 ทวิ", icon: I.tax },
{ section: "ผู้คน" },
{ key: "customers", label: "ลูกค้า (CRM)", icon: I.user },
{ key: "vendors", label: "Vendor/ผู้ขาย", icon: I.building },
{ key: "hr", label: "พนักงาน + HR", icon: I.briefcase },
{ section: "โปรเจกต์" },
{ key: "projects", label: "โปรเจกต์/Job", icon: I.cube3d },
{ key: "activity", label: "กิจกรรมและแชท", icon: I.msg },
{ section: "ระบบ" },
{ key: "users", label: "ผู้ใช้และสิทธิ์", icon: I.shield },
{ key: "settings", label: "ตั้งค่าบริษัท", icon: I.cog },
{ key: "db-status", label: "การเชื่อมต่อ DB", icon: I.db, adminOnly: true },
{ key: "manual", label: "คู่มือการใช้งาน", icon: I.book }];


// Re-render on company-settings change
function useCompany() {
  const [, force] = useStateApp(0);
  useEffectApp(() => {
    const h = () => force((n) => n + 1);
    window.addEventListener("sss-company-changed", h);
    window.addEventListener("sss-profiles-changed", h);
    window.addEventListener("sss-users-changed", h);
    window.addEventListener("sss-session-changed", h);
    return () => {
      window.removeEventListener("sss-company-changed", h);
      window.removeEventListener("sss-profiles-changed", h);
      window.removeEventListener("sss-users-changed", h);
      window.removeEventListener("sss-session-changed", h);
    };
  }, []);
  return window.SSSData.Company;
}

function Sidebar({ current, navigate, collapsed, mobileOpen }) {
  const C = useCompany();
  // ซ่อนเมนูตามสิทธิ์รายหน้า (per-page) ของบทบาทผู้ใช้ที่ login
  const P = window.Perms;
  const sessUser = window.Session && window.Session.get();
  const isAdminUser = sessUser?.isAdmin;
  const canSee = (key) => {
    const item = NAV.find(n => n.key === key);
    if (item?.adminOnly && !isAdminUser) return false;
    return key === "manual" || (!P ? true : P.canSee(key));
  };
  const visibleNav = [];
  for (let i = 0; i < NAV.length; i++) {
    const n = NAV[i];
    if (n.section) {
      let any = false;
      for (let j = i + 1; j < NAV.length && !NAV[j].section; j++) {if (canSee(NAV[j].key)) {any = true;break;}}
      if (any) visibleNav.push(n);
    } else if (canSee(n.key)) {
      visibleNav.push(n);
    }
  }
  const logo = (C.logoText || C.shortName || "SSS").slice(0, 3).toUpperCase();
  return (
    <div className={`sidebar ${mobileOpen ? "open" : ""}`}>
      <div className="sidebar-brand">
        <div className="brand-logo" style={{ fontSize: "20px" }}>S</div>
        {!collapsed && <div style={{ minWidth: 0 }}>
          <div className="brand-name">TRIPLES CREATIVE</div>
          <div className="brand-sub">{C.tagline || "โปรแกรมบริหารจัดการ"}</div>
        </div>}
      </div>
      <div className="nav">
        {visibleNav.map((n, i) => {
          if (n.section) return <div key={i} className="nav-section">{!collapsed && <span>{n.section}</span>}</div>;
          const active = n.key === current || current.startsWith(n.key + "/");
          return (
            <div key={n.key} className={`nav-item ${active ? "active" : ""}`} onClick={() => navigate(n.key)} title={n.label}>
              {n.icon && React.createElement(n.icon, { className: "icon", size: 16 })}
              <span className="label">{n.label}</span>
              {n.badge && <span className="count">{n.badge}</span>}
            </div>);

        })}
      </div>
      <div className="sidebar-foot">
        {(() => {
          const sessEmp = window.Session && window.Session.employee ? window.Session.employee() : null;
          const avatarName = sessEmp && sessEmp.name || C.currentUser?.name || "ปิยะ ศรีสวัสดิ์";
          return window.RankAvatar ?
          <window.RankAvatar name={avatarName} size={32} /> :
          <div className="avatar">{C.currentUser?.initials || "ปศ"}</div>;
        })()}
        {!collapsed &&
        <div className="who" style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13, fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{C.currentUser?.name || "ปิยะ ศรีสวัสดิ์"}</div>
            <div style={{ fontSize: 11, color: "var(--ink-3)" }} data-comment-anchor="a8833ee47d-div-116-13">{C.currentUser?.role || "Admin · เจ้าของกิจการ"}</div>
          </div>
        }
        {window.Session && window.Session.get() && (collapsed ?
          <button className="icon-btn" title="ออกจากระบบ" onClick={() => window.Session.logout()}><I.arrowRight size={13} /></button> :
          <button className="icon-btn" title="ออกจากระบบ" onClick={() => { if (confirm("ออกจากระบบ?")) window.Session.logout(); }} style={{ display:"flex", alignItems:"center", gap:4, fontSize:11, color:"var(--ink-3)", padding:"4px 6px", borderRadius:6 }}>
            <I.arrowRight size={13} /><span>ออก</span>
          </button>
        )}
      </div>
    </div>);

}

// ── แปลงวันที่ภาษาไทย "7 มิ.ย. 2569" → JS Date ──
const THAI_MONTHS = { 'ม.ค.':0,'ก.พ.':1,'มี.ค.':2,'เม.ย.':3,'พ.ค.':4,'มิ.ย.':5,'ก.ค.':6,'ส.ค.':7,'ก.ย.':8,'ต.ค.':9,'พ.ย.':10,'ธ.ค.':11 };
function parseThaiDate(s) {
  if (!s) return null;
  const m = s.match(/(\d+)\s+(\S+\.?)\s+(\d+)/);
  if (!m) return null;
  const mo = THAI_MONTHS[m[2]];
  if (mo === undefined) return null;
  return new Date(parseInt(m[3]) - 543, mo, parseInt(m[1]));
}

function buildNotifs(sess, navigate) {
  const D = window.SSSData;
  const today = new Date(); today.setHours(0,0,0,0);
  const soon = new Date(today); soon.setDate(soon.getDate() + 7);
  const result = [];

  if (sess?.isAdmin) {
    // บิลค้างเกินกำหนด
    const overdue = (D.BillingNotes || []).filter(b => {
      if (b.status === 'เก็บเงินแล้ว') return false;
      const d = parseThaiDate(b.dueDate); return d && d < today;
    });
    if (overdue.length > 0) result.push({ icon: I.invoice, tone: 'var(--danger)',
      title: `บิลเกินกำหนด ${overdue.length} รายการ`,
      desc: overdue.slice(0,2).map(b => b.no + ' · ' + b.customer).join(' · '), go: 'billing-notes' });

    // ใบแจ้งหนี้ค้างชำระ
    const invOverdue = (D.Invoices || []).filter(inv => {
      if (inv.status === 'ชำระแล้ว') return false;
      const d = parseThaiDate(inv.due); return d && d < today;
    });
    if (invOverdue.length > 0) result.push({ icon: I.invoice, tone: 'var(--danger)',
      title: `Invoice ค้างชำระ ${invOverdue.length} รายการ`,
      desc: invOverdue.slice(0,2).map(v => v.no).join(', '), go: 'invoices' });

    // ภาษีใกล้ครบกำหนด
    const taxDue = (D.TaxFilings || []).filter(t => {
      if (t.status !== 'รอยื่น') return false;
      const d = parseThaiDate(t.dueDate); return d && d <= soon;
    });
    if (taxDue.length > 0) result.push({ icon: I.tax, tone: 'var(--warning)',
      title: `ภาษีใกล้ครบกำหนด ${taxDue.length} รายการ`,
      desc: taxDue.slice(0,3).map(t => t.code + ' ครบ ' + t.dueDate).join(' · '), go: 'accounting' });
  }

  // งานของฉันวันนี้
  const emp = sess && window.Session ? window.Session.employee() : null;
  if (emp) {
    const todayStr = today.toISOString().slice(0,10);
    const myTasks = (D.DailyTasks || []).filter(t =>
      t.date === todayStr && Array.isArray(t.assignees) && t.assignees.includes(emp.id) && t.status !== 'ทำเสร็จ');
    if (myTasks.length > 0) result.push({ icon: I.briefcase || I.check, tone: 'var(--info)',
      title: `งานวันนี้ ${myTasks.length} รายการรอดำเนินการ`,
      desc: myTasks.slice(0,2).map(t => t.title).join(' · '), go: 'my-work' });
  }

  // ถูกแท็กในแชท
  if (sess?.name && window.csRooms && window.csUnread) {
    const rooms = window.csRooms(sess.name);
    let mentions = 0;
    rooms.forEach(r => {
      const un = window.csUnread(r.id, sess.name);
      mentions += un.filter(m => m.text && m.text.includes('@' + sess.name)).length;
    });
    if (mentions > 0) result.push({ icon: I.msg, tone: 'var(--warning)',
      title: `มีคนแท็กคุณ ${mentions} ครั้งในแชท`, desc: 'คลิกเพื่อดู', go: 'activity' });
  }

  return result;
}

function annLoad() {
  try { return JSON.parse(localStorage.getItem('sss-announcement') || 'null') || { text: '', active: false, color: '#7c3aed' }; } catch { return { text: '', active: false, color: '#7c3aed' }; }
}
function annSave(v) {
  localStorage.setItem('sss-announcement', JSON.stringify(v));
}

// ── แถบประกาศวิ่ง ──
function AnnouncementBar({ onEdit, isAdmin }) {
  const [ann, setAnn] = useStateApp(annLoad);
  useEffectApp(() => {
    const h = () => setAnn(annLoad());
    window.addEventListener('sss-localstore-polled', h);
    window.addEventListener('sss-announcement-changed', h);
    return () => { window.removeEventListener('sss-localstore-polled', h); window.removeEventListener('sss-announcement-changed', h); };
  }, []);

  // auto-expire
  useEffectApp(() => {
    if (!ann.active || !ann.expires) return;
    const ms = new Date(ann.expires) - Date.now();
    if (ms <= 0) { annSave({ ...ann, active: false }); setAnn(a => ({ ...a, active: false })); return; }
    const t = setTimeout(() => { annSave({ ...ann, active: false }); setAnn(a => ({ ...a, active: false })); }, ms);
    return () => clearTimeout(t);
  }, [ann.active, ann.expires]);

  const stopNow = () => { const v = { ...ann, active: false }; annSave(v); localStorage.setItem('sss-announcement', JSON.stringify(v)); window.dispatchEvent(new Event('sss-announcement-changed')); };

  if (!ann.active || !ann.text) return null;
  const speed = Math.max(14, ann.text.length * 0.2);
  return (
    <div style={{ background: ann.color || '#7c3aed', color: '#fff', overflow: 'hidden', height: 34, display: 'flex', alignItems: 'center', flexShrink: 0, position: 'relative' }}>
      <style>{`@keyframes ticker { 0%{transform:translateX(100vw)} 100%{transform:translateX(-100%)} }`}</style>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, whiteSpace: 'nowrap', animation: 'ticker ' + speed + 's linear infinite', fontSize: 13, fontWeight: 600, paddingRight: isAdmin ? 130 : 0 }}>
        📢 {ann.text} &nbsp;&nbsp;&nbsp;·&nbsp;&nbsp;&nbsp; 📢 {ann.text} &nbsp;&nbsp;&nbsp;·&nbsp;&nbsp;&nbsp; 📢 {ann.text}
      </div>
      {isAdmin && (
        <div style={{ position: 'absolute', right: 6, display: 'flex', gap: 4 }}>
          <button onClick={onEdit} style={{ background: 'rgba(255,255,255,0.22)', border: 'none', color: '#fff', borderRadius: 5, padding: '2px 9px', fontSize: 11, cursor: 'pointer', fontFamily: 'var(--font)' }}>✏️ แก้ไข</button>
          <button onClick={stopNow} style={{ background: 'rgba(0,0,0,0.25)', border: 'none', color: '#fff', borderRadius: 5, padding: '2px 9px', fontSize: 11, cursor: 'pointer', fontFamily: 'var(--font)' }}>■ หยุด</button>
        </div>
      )}
    </div>
  );
}

// ── modal ตั้งค่าประกาศ ──
function AnnouncementModal({ onClose }) {
  const raw = annLoad();
  const [text, setText] = useStateApp(raw.text || '');
  const [active, setActive] = useStateApp(!!raw.text && raw.active !== false);
  const [color, setColor] = useStateApp(raw.color || '#7c3aed');
  const [expireMin, setExpireMin] = useStateApp('');
  const save = () => {
    const expires = expireMin ? new Date(Date.now() + parseInt(expireMin) * 60000).toISOString() : null;
    const v = { text, active, color, ...(expires ? { expires } : {}) };
    annSave(v);
    window.dispatchEvent(new Event('sss-announcement-changed'));
    onClose();
  };
  const stopAll = () => { annSave({ ...raw, active: false }); window.dispatchEvent(new Event('sss-announcement-changed')); onClose(); };
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'rgba(0,0,0,0.4)', display: 'grid', placeItems: 'center' }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{ background: 'var(--surface)', borderRadius: 'var(--radius)', padding: 24, width: 440, maxWidth: '92vw', boxShadow: 'var(--shadow-lg)' }}>
        <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 16 }}>📢 ตั้งค่าประกาศ</div>
        <div className="field" style={{ marginBottom: 12 }}><label>ข้อความประกาศ</label>
          <textarea className="input" rows={3} value={text} onChange={e => setText(e.target.value)} placeholder="เช่น: ประชุมทีมวันศุกร์เวลา 16:00 น. · หยุดพักกลางวัน 12:00-13:00" style={{ resize: 'vertical' }} />
        </div>
        <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap', marginBottom: 12 }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, cursor: 'pointer' }}>
            <input type="checkbox" checked={active} onChange={e => setActive(e.target.checked)} style={{ accentColor: 'var(--brand)' }} />
            เปิดแสดง
          </label>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>🎨 สีแถบ
            <input type="color" value={color} onChange={e => setColor(e.target.value)} style={{ width: 32, height: 24, border: 'none', borderRadius: 4, cursor: 'pointer' }} />
          </label>
          <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>⏱ หยุดอัตโนมัติหลัง
            <select className="input" value={expireMin} onChange={e => setExpireMin(e.target.value)} style={{ height: 28, fontSize: 12, padding: '0 6px', width: 'auto' }}>
              <option value="">ไม่กำหนด</option>
              <option value="30">30 นาที</option>
              <option value="60">1 ชั่วโมง</option>
              <option value="120">2 ชั่วโมง</option>
              <option value="480">8 ชั่วโมง</option>
              <option value="1440">1 วัน</option>
            </select>
          </label>
        </div>
        {text && <div style={{ background: color, color: '#fff', borderRadius: 6, padding: '6px 12px', fontSize: 12, marginBottom: 14, fontWeight: 600, overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>📢 ตัวอย่าง: {text}</div>}
        <div style={{ display: 'flex', gap: 8, justifyContent: 'space-between' }}>
          <button className="btn danger" onClick={stopAll}>■ หยุดประกาศ</button>
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="btn" onClick={onClose}>ยกเลิก</button>
            <button className="btn primary" onClick={save}>บันทึกและแสดง</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function DBStatusDot({ navigate }) {
  const [st, setSt] = useStateApp(() => window.SSSDBStatus ? window.SSSDBStatus.state : 'idle');
  useEffectApp(() => {
    if (!window.SSSDBStatus) return;
    setSt(window.SSSDBStatus.state);
    return window.SSSDBStatus.on(s => setSt(s.state));
  }, []);
  const colors = { idle: '#22c55e', saving: '#f59e0b', loading: '#3b82f6', error: '#ef4444', offline: '#9ca3af' };
  const labels = { idle: 'DB: เชื่อมต่อปกติ', saving: 'DB: กำลังบันทึก…', loading: 'DB: กำลังโหลด…', error: 'DB: เกิดข้อผิดพลาด', offline: 'DB: ออฟไลน์' };
  const anim = st === 'saving' || st === 'loading';
  return (
    <button className="icon-btn" title={labels[st] || 'DB'} onClick={() => navigate('db-status')} style={{ position: 'relative', overflow: 'visible' }}>
      <I.db size={14} />
      <span style={{ position: 'absolute', top: 3, right: 2, width: 7, height: 7, borderRadius: '50%',
        background: colors[st] || '#9ca3af', border: '1.5px solid var(--surface)', pointerEvents: 'none',
        animation: anim ? 'db-dot-pulse 1.2s ease-in-out infinite' : 'none' }} />
      <style>{`@keyframes db-dot-pulse{0%,100%{opacity:1}50%{opacity:0.3}}`}</style>
    </button>
  );
}

function Topbar({ navigate, current, theme, toggleTheme, openMobile, toggleSidebar, onOpenAnn }) {
  const C = useCompany();
  const crumb = NAV.find((n) => n.key === current || n.key && current.startsWith(n.key + "/"))?.label || "หน้าหลัก";
  const [notifOpen, setNotifOpen] = useStateApp(false);
  const sess = window.Session ? window.Session.get() : null;
  const isAdmin = sess?.isAdmin;
  const notifs = buildNotifs(sess, navigate);

  const openNotif = (n) => {setNotifOpen(false); navigate(n.go);};
  return (
    <div className="topbar">
      <button className="icon-btn hamburger" onClick={openMobile}><I.menu size={16} /></button>
      <button className="icon-btn collapse-toggle" onClick={toggleSidebar} title="ย่อ/ขยาย sidebar"><I.menu size={14} /></button>
      <div className="crumb">SSS · <b>{crumb}</b></div>
      <div className="topbar-actions">
        {window.GlobalSearch ?
        <window.GlobalSearch navigate={navigate} /> :
        <div className="search"><I.search size={14} /><input placeholder="ค้นหาเอกสาร, ลูกค้า, สินค้า…" /><span className="kbd">⌘K</span></div>}
        <button className="icon-btn" onClick={toggleTheme} title="เปลี่ยนโหมด">
          {theme === "dark" ? <I.sun size={14} /> : <I.moon size={14} />}
        </button>
        {isAdmin && <DBStatusDot navigate={navigate} />}
        {isAdmin && <button className="icon-btn" title="ประกาศ" onClick={onOpenAnn}>📢</button>}
        <div style={{ position: "relative" }}>
          <button className="icon-btn" title="แจ้งเตือน" onClick={() => setNotifOpen((o) => !o)}><I.bell size={14} />{notifs.length > 0 && <span className="dot" />}</button>
          {notifOpen &&
          <>
              <div onClick={() => setNotifOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 40 }} />
              <div style={{ position: "absolute", top: "calc(100% + 8px)", right: 0, width: 340, zIndex: 41,
              background: "var(--surface)", border: "1px solid var(--line-strong)", borderRadius: "var(--radius)",
              boxShadow: "var(--shadow-lg)", overflow: "hidden" }}>
                <div style={{ padding: "11px 14px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                  <span style={{ fontSize: 13, fontWeight: 600 }}>การแจ้งเตือน</span>
                  <span style={{ fontSize: 11, color: "var(--ink-3)" }}>{notifs.length} รายการ</span>
                </div>
                {notifs.length === 0 && <div style={{ padding: "20px 14px", textAlign: "center", fontSize: 13, color: "var(--ink-3)" }}>ไม่มีการแจ้งเตือน</div>}
                {notifs.map((n, i) =>
              <div key={i} onClick={() => openNotif(n)} style={{ display: "flex", gap: 10, padding: "11px 14px",
                borderBottom: i < notifs.length - 1 ? "1px solid var(--line-soft)" : "none", cursor: "pointer" }}
              onMouseOver={(e) => e.currentTarget.style.background = "var(--surface-2)"}
              onMouseOut={(e) => e.currentTarget.style.background = "transparent"}>
                    <div style={{ width: 30, height: 30, borderRadius: 7, flexShrink: 0, display: "grid", placeItems: "center",
                  background: "var(--surface-2)", color: n.tone }}>{React.createElement(n.icon, { size: 15 })}</div>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 500 }}>{n.title}</div>
                      <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 1 }}>{n.desc}</div>
                    </div>
                  </div>
              )}
                <button onClick={() => {setNotifOpen(false);navigate("activity");}} style={{ width: "100%", padding: "10px 14px",
                background: "var(--surface-2)", border: "none", borderTop: "1px solid var(--line)", cursor: "pointer",
                fontSize: 12, color: "var(--ink-2)", fontFamily: "var(--font)" }}>ดูกิจกรรมทั้งหมด</button>
              </div>
            </>
          }
        </div>
        <button className="icon-btn" title="ตั้งค่า" onClick={() => navigate("settings")}><I.cog size={14} /></button>
      </div>
    </div>);

}

function AIAssistant() {
  const [open, setOpen] = useStateApp(false);
  const [busy, setBusy] = useStateApp(false);
  const [msgs, setMsgs] = useStateApp([
  { role: "bot", text: "สวัสดีครับ ผมเป็น AI ผู้ช่วยของ SSS — ถามอะไรได้ทั้งสรุปยอด ทำใบเสนอราคา หาข้อมูลลูกค้า หรือเช็คภาษีก็ได้ครับ" }]
  );
  const [input, setInput] = useStateApp("");
  const bodyRef = useRefApp(null);

  const suggestions = [
  "สรุปยอดขายเดือนนี้ให้หน่อย",
  "ลูกค้ารายไหนค้างเงินมากที่สุด?",
  "ภาษีอะไรต้องยื่นเดือนหน้าบ้าง",
  "ช่วยร่างใบเสนอราคาให้ Innofoods",
  "ทำไมกำไรเดือนนี้น้อยลง?"];


  const send = async (text) => {
    const t = text || input;
    if (!t.trim()) return;
    setMsgs((m) => [...m, { role: "user", text: t }, { role: "bot", text: "...", loading: true }]);
    setInput("");
    setBusy(true);

    // Compose context summary
    const D = window.SSSData;
    const ctx = `คุณเป็นผู้ช่วยภายในของโปรแกรม SSS (บริษัท SSS สแตนเลส แอนด์ เมทัล จำกัด — ผลิตงานเหล็ก/สแตนเลส/CNC laser/3D CAD)
ข้อมูลภาพรวมเดือนนี้ (พ.ค. 2569):
- ยอดขาย ฿1,295,400 ยอดซื้อ ฿1,156,700
- ลูกค้าค้างชำระ ฿${D.Invoices.filter((i) => i.status !== 'ชำระแล้ว').reduce((s, i) => s + i.amount - i.paid, 0).toLocaleString()}
- ลูกค้าค้างนานสุด: บริษัท ไทยเมทัลฟอร์ม (฿285,000 เกินกำหนด)
- ภาษีที่ต้องยื่น มิ.ย.: ภ.ง.ด.1 (7 มิ.ย.), ภ.พ.30 (15 มิ.ย.), สปส.1-10 (15 มิ.ย.)
- โปรเจกต์เปิด 4 งาน รวมงบ ฿1.2M
- สต็อกใกล้หมด: 316L 2.0mm (8 แผ่น), เหล็กกล่อง 50x50 (12 เส้น)
ตอบสั้น กระชับ ภาษาไทย ใช้บูลเลตได้ ถ้าเป็นการขอทำเอกสารบอกว่ากำลังร่างให้และให้ดูในหน้าที่เกี่ยวข้อง`;

    try {
      const reply = await window.claude.complete({
        messages: [
        { role: "user", content: ctx + "\n\nคำถาม: " + t }]

      });
      setMsgs((m) => {
        const next = [...m];
        next[next.length - 1] = { role: "bot", text: reply };
        return next;
      });
    } catch (e) {
      setMsgs((m) => {
        const next = [...m];
        next[next.length - 1] = { role: "bot", text: "ขออภัยครับ ยังเชื่อมต่อ AI ไม่ได้ในขณะนี้ ลองใหม่อีกครั้ง" };
        return next;
      });
    } finally {
      setBusy(false);
      setTimeout(() => bodyRef.current && (bodyRef.current.scrollTop = bodyRef.current.scrollHeight), 50);
    }
  };

  if (!open) {
    return (
      <button className="ai-btn" onClick={() => setOpen(true)}>
        <I.sparkle size={16} />
        <span>ผู้ช่วย AI</span>
      </button>);

  }

  return (
    <div className="ai-panel">
      <div className="ai-head">
        <div style={{ width: 28, height: 28, background: "var(--accent)", color: "var(--accent-ink)", borderRadius: "50%", display: "grid", placeItems: "center" }}>
          <I.sparkle size={14} />
        </div>
        <div style={{ flex: 1 }}>
          <h4>ผู้ช่วย AI · SSS</h4>
          <div style={{ fontSize: 11, color: "var(--ink-3)" }}>เชื่อมต่อกับข้อมูลในระบบ</div>
        </div>
        <button className="icon-btn" onClick={() => setOpen(false)}><I.close size={14} /></button>
      </div>
      <div className="ai-body" ref={bodyRef}>
        {msgs.map((m, i) =>
        <div key={i} className={`ai-msg ${m.role}`}>{m.loading ? <Dots /> : m.text}</div>
        )}
      </div>
      {msgs.length < 3 &&
      <div className="ai-suggest">
          {suggestions.map((s) => <div key={s} className="chip" onClick={() => send(s)}>{s}</div>)}
        </div>
      }
      <div className="ai-foot">
        <input value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && !busy && send()} placeholder="ถามอะไรก็ได้…" />
        <button className="icon-btn" onClick={() => send()} disabled={busy} style={{ background: "var(--accent)", color: "var(--accent-ink)", border: "none" }}>
          <I.send size={14} />
        </button>
      </div>
    </div>);

}

function Dots() {
  return (
    <span style={{ display: "inline-flex", gap: 4 }}>
      {[0, 1, 2].map((i) =>
      <span key={i} style={{
        width: 6, height: 6, borderRadius: "50%", background: "var(--ink-3)",
        animation: `dot 1.2s ${i * 0.15}s infinite ease-in-out`
      }} />
      )}
      <style>{`@keyframes dot{0%,80%,100%{opacity:0.3;transform:scale(0.8)}40%{opacity:1;transform:scale(1)}}`}</style>
    </span>);

}

function App() {
  const [route, setRoute] = useStateApp(() => window.location.hash.replace("#/", "") || "dashboard");
  const [theme, setTheme] = useStateApp(() => localStorage.getItem("sss-theme") || "light");
  const [collapsed, setCollapsed] = useStateApp(false);
  const [mobileOpen, setMobileOpen] = useStateApp(false);
  const [session, setSession] = useStateApp(() => window.Session ? window.Session.get() : null);
  const [dbReady, setDbReady] = useStateApp(false);
  const [annModalOpen, setAnnModalOpen] = useStateApp(false);
  const [, forceSync] = useStateApp(0);

  useEffectApp(() => {
    const h = () => setSession(window.Session ? window.Session.get() : null);
    window.addEventListener("sss-session-changed", h);
    return () => window.removeEventListener("sss-session-changed", h);
  }, []);

  // re-render หน้าปัจจุบันเมื่อ poll ได้ข้อมูลใหม่จากเครื่องอื่น (ข้อมูลตรงกันทุกเครื่อง)
  useEffectApp(() => {
    const h = () => forceSync(n => n + 1);
    window.addEventListener("sss-data-synced", h);
    return () => window.removeEventListener("sss-data-synced", h);
  }, []);

  useEffectApp(() => {
    if (window.SSSSync) {
      window.SSSSync.load().finally(() => setDbReady(true));
    } else {
      setDbReady(true);
    }
  }, []);

  useEffectApp(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("sss-theme", theme);
  }, [theme]);

  useEffectApp(() => {
    const onHash = () => setRoute(window.location.hash.replace("#/", "") || "dashboard");
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  const navigate = (path) => {
    window.location.hash = "#/" + path;
    setMobileOpen(false);
    document.querySelector(".content")?.scrollTo({ top: 0 });
  };

  // Routing
  const renderRoute = () => {
    const parts = route.split("/");
    const root = parts[0];
    const map = {
      dashboard: window.Dashboard,
      "daily-delivery": window.DailyDeliveryPage,
      cashbook: window.CashbookPage,
      quotations: window.Quotations,
      invoices: window.Invoices,
      "delivery-notes": window.DeliveryNotes,
      "tax-invoices": window.TaxInvoices,
      "billing-notes": window.BillingNotes,
      receipts: window.Receipts,
      "purchase-orders": window.PurchaseOrders,
      expenses: window.Expenses,
      "payment-vouchers": window.PaymentVouchers,
      "cash-advances": window.PettyCash,
      "company-cash": window.CompanyCash,
      "bank-accounts": window.BankAccountsPage,
      "receipt-vouchers": window.ReceiptVouchers,
      inventory: window.InventoryProducts,
      "stock-movements": window.StockMovements,
      barcode: window.Barcode,
      payroll: window.Payroll,
      "qr-clock": window.QRClock,
      "my-work": window.MyWork,
      kpi: window.KPIPage,
      accounting: window.Accounting,
      "wht-certs": window.WHTCertificates,
      customers: window.Customers,
      vendors: window.Vendors,
      hr: window.HR,
      projects: window.Projects,
      activity: window.ActivityPage,
      users: window.Users,
      settings: window.Settings,
      "db-status": window.DBStatusPage,
      manual: window.Manual
    };

    // ⛔ กันเข้าถึงหน้าที่ไม่มีสิทธิ์ (พิมพ์ URL ตรง ๆ ก็เข้าไม่ได้)
    if (window.Perms && map[root] && !window.Perms.canSee(root)) {
      const go = window.Perms.firstVisiblePage();
      return (
        <div style={{ display: "grid", placeItems: "center", minHeight: "60vh" }}>
          <div style={{ textAlign: "center", maxWidth: 420 }}>
            <div style={{ width: 56, height: 56, borderRadius: "50%", background: "var(--surface-3)", display: "grid", placeItems: "center", margin: "0 auto 14px" }}><I.shield size={24} /></div>
            <div style={{ fontSize: 17, fontWeight: 700, marginBottom: 6 }}>ไม่มีสิทธิ์เข้าถึงหน้านี้</div>
            <div style={{ fontSize: 13, color: "var(--ink-3)", marginBottom: 16 }}>บัญชีของคุณไม่ได้รับสิทธิ์เปิดเมนูนี้ — ติดต่อผู้ดูแลระบบหากต้องการเข้าถึง</div>
            <button className="btn primary" onClick={() => navigate(go)}>ไปหน้าที่เข้าได้</button>
          </div>
        </div>);

    }

    // Detail routes
    if (root === "quotations" && parts[1] && parts[1] !== "new") {
      return <window.QuotationDetail navigate={navigate} />;
    }
    if (root === "delivery-notes" && parts[1] && parts[1] !== "new") {
      return <window.DeliveryNoteDetail navigate={navigate} />;
    }
    if (root === "receipts" && parts[1] && parts[1] !== "new") {
      return <window.ReceiptDetail navigate={navigate} />;
    }
    if (root === "receipt-vouchers" && parts[1] && parts[1] !== "new") {
      return <window.ReceiptVoucherDetail docId={parts[1]} navigate={navigate} />;
    }
    // Universal detail for the rest
    const UDETAIL = {
      invoices: "invoice",
      "tax-invoices": "tax-invoice",
      "billing-notes": "billing-note",
      "purchase-orders": "purchase-order",
      "payment-vouchers": "payment-voucher"
    };
    if (UDETAIL[root] && parts[1] && parts[1] !== "new") {
      return <window.UniversalDocDetail docType={UDETAIL[root]} docId={parts[1]} navigate={navigate} />;
    }
    const Comp = map[root] || window.Dashboard;
    return <Comp navigate={navigate} />;
  };

  // รอโหลดข้อมูลจาก Supabase ก่อน
  if (!dbReady) {
    return (
      <div style={{ display:"grid", placeItems:"center", height:"100vh", background:"#ece9f6", fontFamily:"var(--font)" }}>
        <div style={{ textAlign:"center" }}>
          <div style={{ fontSize:48, marginBottom:16 }}>⚡</div>
          <div style={{ fontFamily:"var(--display)", fontWeight:800, fontSize:18, color:"#1a1430", marginBottom:6 }}>โปรแกรมบริหารจัดการ SSS</div>
          <div style={{ fontSize:13, color:"#726a8c" }}>กำลังเชื่อมต่อฐานข้อมูล…</div>
        </div>
      </div>
    );
  }

  // หน้าเข้าสู่ระบบ — แสดงเต็มจอ ไม่อยู่ในกริด .shell (กันโดนบีบความกว้าง)
  if (!session && window.LoginScreen) {
    return (
      <>
        {window.UpdateBanner && <window.UpdateBanner />}
        <window.LoginScreen />
        <window.UI.ToastHub />
      </>);
  }

  return (
    <div className={`shell ${collapsed ? "collapsed" : ""}`}>
      <>
      {window.UpdateBanner && <window.UpdateBanner />}
      {mobileOpen && <div className="scrim" onClick={() => setMobileOpen(false)} />}
      <Sidebar current={route} navigate={navigate} collapsed={collapsed} mobileOpen={mobileOpen} />
      <div className="main">
        <Topbar
            navigate={navigate}
            current={route}
            theme={theme}
            toggleTheme={() => setTheme((t) => t === "dark" ? "light" : "dark")}
            openMobile={() => setMobileOpen((o) => !o)}
            toggleSidebar={() => setCollapsed((c) => !c)}
            onOpenAnn={() => setAnnModalOpen(true)} />
        <AnnouncementBar isAdmin={session?.isAdmin} onEdit={() => setAnnModalOpen(true)} />
        {annModalOpen && <AnnouncementModal onClose={() => setAnnModalOpen(false)} />}
        <div className="content">
          {renderRoute()}
        </div>
      </div>
      <AIAssistant />
      {window.ChatWidget && <window.ChatWidget />}
      <window.UI.ToastHub />
      {window.DeliveryAlertHost && <window.DeliveryAlertHost />}
      {window.NewDocHost && <window.NewDocHost />}
      {window.ReceiptVoucherHost && <window.ReceiptVoucherHost />}
      {window.WHTCertHost && <window.WHTCertHost />}
      </>
    </div>);

}

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