/* global React, ReactDOM, window */
const { useState, useEffect } = React;

// ── Nav model: icon + Thai label per page, grouped for the sidebar ───────────
function NavIcon({ k }) {
  const P = {
    dashboard:  <><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></>,
    realtime:   <><circle cx="12" cy="12" r="3.2"/><path d="M4 8V5.5A1.5 1.5 0 0 1 5.5 4H8M16 4h2.5A1.5 1.5 0 0 1 20 5.5V8M20 16v2.5a1.5 1.5 0 0 1-1.5 1.5H16M8 20H5.5A1.5 1.5 0 0 1 4 18.5V16"/></>,
    attendance: <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    employee:   <><path d="M16 21v-2a4 4 0 0 0-8 0v2"/><circle cx="12" cy="7" r="4"/></>,
    department: <><path d="M3 21h18M5 21V7l7-4 7 4v14M9 21v-5h6v5M9 10h.01M15 10h.01"/></>,
    leave:      <><rect x="3" y="4" width="18" height="17" rx="2.5"/><path d="M3 9h18M8 2v4M16 2v4"/><path d="M9 15l2 2 4-4"/></>,
    holiday:    <><rect x="3" y="4" width="18" height="17" rx="2.5"/><path d="M3 9h18M8 2v4M16 2v4"/></>,
    announce:   <><path d="M3 11v2a1 1 0 0 0 1 1h2l5 4V6L6 10H4a1 1 0 0 0-1 1z"/><path d="M16 8a5 5 0 0 1 0 8"/></>,
    shift:      <><circle cx="12" cy="12" r="9"/><path d="M12 8v4l2 2"/></>,
    schedule:   <><rect x="3" y="4" width="18" height="17" rx="2.5"/><path d="M3 9h18M8 2v4M16 2v4M7 13h3M7 17h3M14 13h3"/></>,
    payroll:    <><rect x="2" y="6" width="20" height="12" rx="2"/><circle cx="12" cy="12" r="2.5"/><path d="M6 10v4M18 10v4"/></>,
    report:     <><path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/></>,
    device:     <><rect x="4" y="3" width="16" height="14" rx="2"/><path d="M9 21h6M12 17v4"/></>,
    settings:   <><circle cx="12" cy="12" r="3"/><path d="M19.4 13a7.9 7.9 0 0 0 .1-1 7.9 7.9 0 0 0-.1-1l2-1.6-2-3.4-2.4 1a7.5 7.5 0 0 0-1.7-1L14 0h-4l-.4 2.6a7.5 7.5 0 0 0-1.7 1l-2.4-1-2 3.4 2 1.6a8 8 0 0 0 0 2l-2 1.6 2 3.4 2.4-1a7.5 7.5 0 0 0 1.7 1L10 24h4l.4-2.6a7.5 7.5 0 0 0 1.7-1l2.4 1 2-3.4z" transform="scale(0.83) translate(2.4 2.4)"/></>,
    approvals:  <><path d="M9 12l2 2 4-4"/><path d="M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9"/></>,
    expense:    <><path d="M20 12V8H6a2 2 0 0 1 0-4h12v4"/><path d="M4 6v12a2 2 0 0 0 2 2h14v-4"/><path d="M18 12a2 2 0 0 0 0 4h4v-4z"/></>,
    tasks:      <><rect x="8" y="3" width="8" height="4" rx="1"/><path d="M9 5H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-3"/><path d="M9 12h6M9 16h4"/></>,
    activity:   <><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></>,
    tenants:    <><path d="M3 21h18M6 21V8l6-4 6 4v13"/><path d="M10 21v-5h4v5M10 11h.01M14 11h.01"/></>,
  };
  return <svg viewBox="0 0 24 24">{P[k] || <circle cx="12" cy="12" r="8"/>}</svg>;
}

const PAGE_LABEL = {
  dashboard:'ภาพรวมวันนี้', realtime:'สแกนเรียลไทม์', attendance:'ลงเวลา', employee:'พนักงาน',
  department:'แผนก', leave:'การลา', holiday:'วันหยุด', announce:'ประกาศ',
  approvals:'อนุมัติ', expense:'ค่าใช้จ่าย', tasks:'มอบหมายงาน', activity:'กิจกรรม',
  shift:'กะงาน', schedule:'ตารางเวร', payroll:'เงินเดือน', report:'รายงาน',
  device:'เครื่องสแกน', settings:'ตั้งค่า', tenants:'จัดการลูกค้า',
};
// Resolve a page's visible label, swapping the department label to the
// org-mode term (แผนก / กอง) live from window.T.
function pageLabel(key) {
  if (key === 'department') return (window.T && window.T.dept) || 'แผนก';
  return PAGE_LABEL[key] || key;
}
const NAV_GROUPS = [
  { label:'ส่วนกลาง',     keys:['tenants'] },     // super admin เท่านั้น
  { label:'ทั่วไป',       keys:['dashboard','realtime','attendance'] },
  { label:'คำขอ & อนุมัติ', keys:['approvals','leave','expense','tasks'] },
  { label:'งานบุคคล',     keys:['employee','department','holiday','announce'] },
  { label:'ตารางงาน',     keys:['shift','schedule'] },
  { label:'รายงาน & ระบบ', keys:['payroll','report','activity','device','settings'] },
];

// Pages a given role is allowed to see.
const ROLE_PAGES = {
  // ผู้ดูแลส่วนกลาง (Face in Time) ไม่ผูกกับหน่วยงานใด — เห็นเฉพาะหน้าจัดการลูกค้า
  super_admin: ['tenants'],
  admin:    ['dashboard','realtime','attendance','approvals','leave','expense','tasks','employee','department','holiday','announce','shift','schedule','payroll','report','activity','device','settings'],
  hr:       ['dashboard','realtime','attendance','approvals','leave','expense','tasks','employee','department','holiday','announce','shift','schedule','payroll','report','activity','settings'],
  manager:  ['dashboard','attendance','approvals','leave','expense','tasks','employee','schedule','announce','report','activity'],
  employee: ['dashboard','attendance','leave','expense','tasks','announce'],
};
const ROLE_LABEL = { super_admin:'ผู้ดูแลส่วนกลาง', admin:'ผู้ดูแลระบบ', hr:'เจ้าหน้าที่ HR', manager:'หัวหน้างาน', employee:'พนักงาน' };
const HOME_PAGE = { super_admin:'tenants' };
function homeFor(role) { return HOME_PAGE[role] || 'dashboard'; }

function LoadingSplash() {
  return (
    <div style={{ position:'fixed', inset:0, display:'grid', placeItems:'center', background:'var(--gv-paper)' }}>
      <div style={{ textAlign:'center' }}>
        <img src="/img/logo-tile.svg" alt="Face in Time" style={{ width:72, height:72, borderRadius:17, margin:'0 auto 16px', display:'block' }}/>
        <div style={{ color:'var(--gv-soft)', fontSize:13 }}>กำลังโหลด…</div>
      </div>
    </div>
  );
}

class PageErrorBoundary extends React.Component {
  constructor(props) { super(props); this.state = { err: null }; }
  static getDerivedStateFromError(err) { return { err }; }
  componentDidCatch(err, info) { console.error('[page crash]', err, info); }
  render() {
    if (this.state.err) {
      return (
        <div style={{ padding:48, textAlign:'center' }}>
          <div style={{ fontSize:20, fontWeight:700, marginBottom:8 }}>หน้านี้เกิดข้อผิดพลาด</div>
          <div style={{ fontSize:12.5, color:'var(--gv-soft)', marginBottom:18, wordBreak:'break-word' }}>
            {String((this.state.err && this.state.err.message) || this.state.err)}
          </div>
          <button className="gv-btn ok" onClick={() => { this.setState({ err:null }); window.refreshData && window.refreshData(); }}>ลองใหม่</button>
          <button className="gv-btn no" style={{ marginLeft:8 }} onClick={() => location.reload()}>โหลดหน้าใหม่</button>
        </div>
      );
    }
    return this.props.children;
  }
}

// 1s clock + Thai date, shared by topbar & kiosk.
function useClock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const t = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(t); }, []);
  const p = (n) => String(n).padStart(2, '0');
  const days = ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'];
  const months = ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน','กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'];
  return {
    clock: `${p(now.getHours())}:${p(now.getMinutes())}:${p(now.getSeconds())}`,
    dateStr: `วัน${days[now.getDay()]}ที่ ${now.getDate()} ${months[now.getMonth()]} ${now.getFullYear() + 543}`,
    now,
  };
}

function detectMode() {
  const u = (location.pathname + location.search + location.hash).toLowerCase();
  if (/kiosk|terminal/.test(u)) return 'kiosk';
  if (/view=pass|[?&]m=1|\/pass\b/.test(u)) return 'mobile';
  if (/view=(console|desktop)/.test(u)) return 'desktop';
  try { if (window.matchMedia && window.matchMedia('(max-width: 768px)').matches) return 'mobile'; } catch (_) {}
  return 'desktop';
}

function greetWord(h) { return h < 12 ? 'สวัสดีตอนเช้า' : (h < 17 ? 'สวัสดีตอนบ่าย' : 'สวัสดีตอนเย็น'); }

function App() {
  const [bootState, setBootState] = useState('loading');
  const [active, setActive] = useState('dashboard');
  const [collapsed, setCollapsed] = useState(false);
  const [dayStamp, setDayStamp] = useState(() => new Date().toDateString());
  const [role, setRole] = useState('admin');
  const [mode, setMode] = useState(detectMode);
  const { clock, dateStr, now } = useClock();

  useEffect(() => { window.navigateTo = setActive; }, []);
  useEffect(() => {
    const onResize = () => setMode(detectMode());
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  // Day cutover: at midnight the date rolls to a new day — refresh window.TODAY,
  // re-pull data, and remount the active page (via dayStamp key) so counts reset.
  useEffect(() => {
    const today = new Date().toDateString();
    if (today !== dayStamp) {
      setDayStamp(today);
      const p = (n) => String(n).padStart(2, '0'); const d = new Date();
      window.TODAY = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
      if (window.refreshData) window.refreshData();
    }
  }, [now, dayStamp]);

  useEffect(() => {
    (async () => {
      try {
        const r = await fetch('/api/auth/me', { credentials: 'include' });
        if (!r.ok) { setBootState('login'); return; }
        const me = await r.json();
        await window.dataReady;
        if (!window.CURRENT_USER) await window.refreshData();
        const r2 = me.role || 'employee';
        setRole(r2);
        setActive(homeFor(r2));
        setBootState('app');
      } catch (e) {
        console.error('boot failed:', e);
        setBootState('login');
      }
    })();
  }, []);

  useEffect(() => {
    const allowed = new Set(ROLE_PAGES[role] || ROLE_PAGES.employee);
    if (!allowed.has(active)) setActive(homeFor(role));
  }, [role, active]);

  const handleLogin = async (username, password, deviceId) => {
    const r = await fetch('/api/auth/login', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password, device_id: deviceId || null }),
    });
    if (!r.ok) {
      const d = await r.json().catch(() => ({}));
      throw new Error(d.error || d.detail || 'เข้าสู่ระบบไม่สำเร็จ');
    }
    const data = await r.json();
    await window.refreshData();
    const r2 = data.user.role || 'employee';
    setRole(r2);
    setActive(homeFor(r2));
    setBootState('app');
    return data.user;
  };

  const handleLogout = async () => {
    try { await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); } catch (_) {}
    setBootState('login');
  };

  const renderPage = () => {
    const props = { role };
    switch (active) {
      case 'dashboard':  return <window.Dashboard {...props}/>;
      case 'realtime':   return <window.RealtimePage {...props}/>;
      case 'employee':   return <window.EmployeePage {...props}/>;
      case 'department': return <window.DepartmentPage {...props}/>;
      case 'shift':      return <window.ShiftPage {...props}/>;
      case 'schedule':   return <window.SchedulePage {...props}/>;
      case 'attendance': return <window.AttendancePage {...props}/>;
      case 'holiday':    return <window.HolidayPage {...props}/>;
      case 'leave':      return <window.LeavePage {...props}/>;
      case 'announce':   return window.AnnouncePage ? <window.AnnouncePage {...props}/> : <window.Dashboard {...props}/>;
      case 'approvals':  return window.ApprovalsPage ? <window.ApprovalsPage {...props}/> : <window.Dashboard {...props}/>;
      case 'expense':    return window.ExpensePage ? <window.ExpensePage {...props}/> : <window.Dashboard {...props}/>;
      case 'tasks':      return window.TasksPage ? <window.TasksPage {...props}/> : <window.Dashboard {...props}/>;
      case 'activity':   return window.ActivityPage ? <window.ActivityPage {...props}/> : <window.Dashboard {...props}/>;
      case 'tenants':    return window.TenantsPage ? <window.TenantsPage {...props}/> : <div style={{padding:32}}>ไม่พบหน้าจัดการลูกค้า</div>;
      case 'report':     return <window.ReportPage {...props}/>;
      case 'payroll':    return <window.PayrollPage {...props}/>;
      case 'ai':         return <window.AIPage {...props}/>;
      case 'device':     return <window.DevicePage {...props}/>;
      case 'settings':   return <window.SettingsPage {...props}/>;
      default:           return <window.Dashboard {...props}/>;
    }
  };

  if (bootState === 'loading') return <LoadingSplash/>;
  if (bootState === 'login') {
    return (<>
      <window.LoginPage onLogin={handleLogin}/>
      {window.DialogHost && <window.DialogHost/>}
      {window.ProfileModal && <window.ProfileModal/>}
    </>);
  }

  const allowed = new Set(ROLE_PAGES[role] || ROLE_PAGES.employee);
  const devices = window.DEVICES || [];
  const online = devices.filter((d) => d.online !== false && d.status !== 'offline').length;
  const offline = devices.length - online;
  const tenant = window.TENANT || null;
  const orgName = (tenant && tenant.name)
    || (window.SETTINGS && (window.SETTINGS.org_name || window.SETTINGS.event_name || window.SETTINGS.company_name))
    || 'ตรงเวลา';
  const impersonator = window.IMPERSONATOR || null;

  const leaveImpersonation = async () => {
    try { await fetch('/api/platform/exit', { method: 'POST', credentials: 'include' }); } catch (_) {}
    location.reload();
  };
  const pending = window.PENDING_LEAVES || 0;

  const me = window.CURRENT_USER || {};
  const meName = me.display_name || me.name || me.username || ROLE_LABEL[role] || 'ผู้ใช้';
  const meInitials = (meName || '?').trim().replace(/\s+/g, ' ').split(' ').slice(0, 2).map((s) => s[0]).join('') || 'ผ';

  const badgeFor = (key) => {
    if (key === 'leave') return pending || 0;
    if (key === 'device') return offline || 0;
    return 0;
  };

  // ผู้ดูแลส่วนกลางใช้คอนโซลเดสก์ท็อปเสมอ (ไม่มีหน้า mobile/kiosk ให้)
  // พนักงานทั่วไปเห็นเฉพาะ "บัตรพนักงาน" ของตัวเอง (วันนี้เข้ากี่โมง / วันทำงาน / ลา / ขอแก้เวลา) ทุกอุปกรณ์ — ไม่มีคอนโซล
  if ((mode === 'mobile' || role === 'employee') && role !== 'super_admin' && mode !== 'kiosk') {
    const MobileView = role === 'employee' ? window.PassView : window.AdminMobileView;
    return (<>
      <MobileView clock={clock} dateStr={dateStr} orgName={orgName} role={role} onLogout={handleLogout} desktop={mode === 'desktop'}/>
      {window.DialogHost && <window.DialogHost/>}
      {window.ProfileModal && <window.ProfileModal/>}
    </>);
  }
  if (mode === 'kiosk' && role !== 'super_admin') {
    return (<>
      <window.KioskView clock={clock} dateStr={dateStr} orgName={orgName} deviceLine={`${online}/${devices.length || 0} DEVICES`}/>
      {window.DialogHost && <window.DialogHost/>}
      {window.ProfileModal && <window.ProfileModal/>}
    </>);
  }

  return (
    <>
      {impersonator && (
        <div style={{
          position:'sticky', top:0, zIndex:60, display:'flex', alignItems:'center', gap:12,
          background:'#FEF3C7', color:'#92400E', borderBottom:'1px solid #FDE68A',
          padding:'8px 18px', fontSize:13, fontWeight:600,
        }}>
          <span>คุณกำลังดูข้อมูลของ <b>{orgName}</b> ในฐานะผู้ดูแลส่วนกลาง ({impersonator})</span>
          <button className="gv-btn no" style={{ marginLeft:'auto', padding:'4px 12px', fontSize:12.5 }}
                  onClick={leaveImpersonation}>ออกจากโหมดนี้</button>
        </div>
      )}
      <div className={`gv-shell ${collapsed ? 'collapsed' : ''}`}>
        {/* ── SIDEBAR ── */}
        <aside className="gv-side">
          <div className="gv-brand">
            <div className="gv-logo" style={{ background: 'none', padding: 0 }}><img src="/img/logo.svg" alt="Face in Time" style={{ width: '100%', height: '100%' }}/></div>
            <div><b>Face in Time</b><span>{role === 'super_admin' ? 'ผู้ดูแลระบบส่วนกลาง' : orgName}</span></div>
          </div>

          {NAV_GROUPS.map((grp) => {
            const keys = grp.keys.filter((k) => allowed.has(k));
            if (!keys.length) return null;
            return (
              <div key={grp.label}>
                <div className="gv-navgrp">{grp.label}</div>
                {keys.map((key) => {
                  const badge = badgeFor(key);
                  return (
                    <button key={key} className={`gv-nav ${active === key ? 'on' : ''}`} onClick={() => setActive(key)}>
                      <NavIcon k={key}/>
                      <span>{pageLabel(key)}</span>
                      {badge > 0 && <span className="badge">{badge}</span>}
                    </button>
                  );
                })}
              </div>
            );
          })}

          <div className="gv-side-foot">
            {role !== 'super_admin' && (
              <div className="gv-devcard">
                <div className="t"><span className={`gv-dot ${offline > 0 && online === 0 ? 'off' : ''}`}/>เครื่องสแกน</div>
                <div className="s">{online}/{devices.length || 0} เครื่อง เชื่อมต่อปกติ{offline > 0 ? ` · ${offline} ออฟไลน์` : ''}</div>
              </div>
            )}
            <button className="gv-nav" style={{ marginTop:4 }} onClick={handleLogout}>
              <svg viewBox="0 0 24 24"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/></svg>
              <span>ออกจากระบบ</span>
            </button>
          </div>
        </aside>

        {/* ── MAIN ── */}
        <div className="gv-main">
          <header className="gv-top">
            <div style={{ display: 'flex', alignItems: 'center', gap: 14, minWidth: 0 }}>
              <button className="gv-collapse" onClick={() => setCollapsed((c) => !c)} title={collapsed ? 'ขยายเมนู' : 'ย่อเมนู'}>
                <svg viewBox="0 0 24 24"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
              </button>
              <div className="gv-hello">
                <b>{greetWord(now.getHours())}, {meName}</b>
                <div className="d">{dateStr} · {active ? pageLabel(active) : ''}</div>
              </div>
            </div>
            <div className="gv-topright">
              <div className="gv-clock"><div className="t">{clock.slice(0, 5)}</div><div className="z">น.</div></div>
              <div className="gv-me" onClick={() => allowed.has('settings') && setActive('settings')}>
                <div style={{ textAlign:'right' }}><div className="n">{meName}</div><div className="r">{ROLE_LABEL[role] || role}</div></div>
                <div className="gv-av">{meInitials}</div>
              </div>
            </div>
          </header>

          <div className="gv-body">
            <PageErrorBoundary key={active + '|' + dayStamp}>{renderPage()}</PageErrorBoundary>
          </div>
        </div>
      </div>

      {window.DialogHost && <window.DialogHost/>}
      {window.ProfileModal && <window.ProfileModal/>}
    </>
  );
}

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