// app.jsx — root. Patient phone + Staff portal (login → admin / caregiver), mobile & desktop.
const { useState: useStateApp, useEffect: useEffectApp } = React;

function useWindowSize() {
  const [s, setS] = useStateApp({ w: window.innerWidth, h: window.innerHeight });
  useEffectApp(() => {
    const f = () => setS({ w: window.innerWidth, h: window.innerHeight });
    window.addEventListener('resize', f);
    return () => window.removeEventListener('resize', f);
  }, []);
  return s;
}

function App() {
  const T = window.TOK, API = window.API;
  const [surface, setSurface] = useStateApp('patient');      // 'patient' | 'staff'
  const [staffView, setStaffView] = useStateApp('mobile');   // 'mobile' | 'desktop'
  const [lang, setLangState] = useStateApp(() => localStorage.getItem('ortho_lang') || 'en');  // 'en' | 'bn'
  const [patientScreen, setPatientScreen] = useStateApp('cover');  // tracks PatientForm inner screen
  const setLang = (v) => { setLangState(v); try { localStorage.setItem('ortho_lang', v); } catch (e) {} };
  const [auth, setAuth] = useStateApp(null);                 // account | null
  const [online, setOnline] = useStateApp(null);             // null = checking · true/false = backend reachable
  const [patients, setPatients] = useStateApp(window.SEED_PATIENTS);
  const [accounts, setAccounts] = useStateApp(window.SEED_ACCOUNTS);
  const [scope, setScope] = useStateApp('today');            // caregiver queue: 'today' | 'all'
  const size = useWindowSize();

  // ── connect to backend (or fall back to in-memory seed) ──
  useEffectApp(() => {
    let alive = true;
    (async () => {
      const ok = await API.init();
      if (!alive) return;
      setOnline(ok);
      if (ok) {
        const acc = await API.me();            // restore an existing session, if any
        if (alive && acc) setAuth(acc);
      }
    })();
    return () => { alive = false; };
  }, []);

  // ── load data for the signed-in role (online) ──
  useEffectApp(() => {
    if (!online || !auth) return;
    if (auth.role === 'admin') API.getAccounts().then(setAccounts).catch(() => {});
    else API.getSubmissions(scope).then(setPatients).catch(() => {});
  }, [online, auth, scope]);

  // ── live queue updates via SSE (online) ──
  useEffectApp(() => {
    if (!online) return;
    return API.subscribe({
      submission: (p) => setPatients(prev => (prev.find(x => x.id === p.id) ? prev.map(x => x.id === p.id ? p : x) : [...prev, p])),
      delete: ({ id }) => setPatients(prev => prev.filter(p => p.id !== id)),
    });
  }, [online]);

  // staff sign-in: server when online, local seed match when not
  const authenticate = async (id, pw) => {
    if (online) return API.login(id, pw);                    // throws on bad credentials
    const acc = accounts.find(a => a.id.toLowerCase() === id.trim().toLowerCase() && a.password === pw);
    if (!acc) throw new Error('invalid_credentials');
    return acc;
  };
  const logout = () => { if (online) API.logout(); setAuth(null); };

  // offline-only patient submit (online path lives in PatientForm via API)
  const handleSubmit = (patient) => {
    if (online) return;
    setPatients(prev => {
      const exists = prev.find(p => p.phone && p.phone === patient.phone);
      const serial = exists ? exists.serial : (Math.max(0, ...prev.map(p => +p.serial || 0)) + 1);
      const full = { ...patient, serial };
      return exists ? prev.map(p => (p.phone === patient.phone ? full : p)) : [...prev, full];
    });
  };
  const deletePatient = (id) => {
    if (online) API.deleteSubmission(id).catch(() => {});
    setPatients(prev => prev.filter(p => p.id !== id));      // optimistic
  };
  const setSeen = (id, seen) => { if (online) API.setSeen(id, seen).catch(() => {}); };
  const createAccount = (acc) => {
    if (online) API.createAccount(acc).then(created => setAccounts(prev => [...prev, { ...acc, ...created }])).catch(() => {});
    else setAccounts(prev => [...prev, acc]);
  };
  const deleteAccount = (id) => {
    if (online) API.deleteAccount(id).catch(() => {});
    setAccounts(prev => prev.filter(a => a.id !== id));
  };
  const submittedPhones = patients.filter(p => p.status === 'submitted' && p.phone).map(p => p.phone);

  const goStaff = () => { setSurface('staff'); };

  // ── scaling helpers ──
  const scaleFor = (w, h, padV) => Math.min(1, (size.h - padV) / h, (size.w - 40) / w);
  const PHONE = { w: 402, h: 874 };
  const DESK = { w: 1240, h: 800 };

  // ── staff content (login or role dashboard) ──
  const staffInner = (compact) => {
    if (!auth) return <window.Login accounts={accounts} lang={lang} onLang={setLang} compact={compact} online={online} authenticate={authenticate} onLogin={setAuth} onBack={() => setSurface('patient')} />;
    if (auth.role === 'admin') return <window.AdminDashboard accounts={accounts} account={auth} lang={lang} onLang={setLang} compact={compact} online={online} onCreate={createAccount} onDelete={deleteAccount} onLogout={logout} />;
    return <window.Dashboard patients={patients} account={auth} lang={lang} onLang={setLang} compact={compact} online={online} scope={scope} onScope={setScope} onLogout={logout} onDelete={deletePatient} onSeen={setSeen} />;
  };

  // ── real phones: render the actual screen full-bleed (no device mockup, no
  //     showcase chrome). The app fills the viewport at any size. ──
  const isMobile = size.w <= 640;
  if (isMobile) {
    return (
      <div style={{ position: 'fixed', inset: 0, overflow: 'hidden', background: T.surface }}>
        {surface === 'patient'
          ? <window.PatientForm onSubmit={handleSubmit} submittedPhones={submittedPhones} online={online} onStaffLogin={goStaff} lang={lang} onLang={setLang} onScreenChange={setPatientScreen} />
          : staffInner(true)}
      </div>
    );
  }

  const caption = surface === 'patient'
    ? 'What the patient sees on their phone — the link you share each morning'
    : (auth ? (auth.role === 'admin' ? 'Admin portal — create and manage staff accounts' : 'Caregiver view — the day’s patients and their complaints') : 'Staff sign in — pre-generated ID & password');

  // ── render frame ──
  let frame;
  if (surface === 'patient') {
    const s = scaleFor(PHONE.w, PHONE.h, 168);
    frame = (
      <div style={{ transform: `scale(${s})`, transformOrigin: 'center center' }}>
        <window.IOSDevice>
          <window.PatientForm onSubmit={handleSubmit} submittedPhones={submittedPhones} online={online} onStaffLogin={goStaff} lang={lang} onLang={setLang} onScreenChange={setPatientScreen} />
        </window.IOSDevice>
      </div>
    );
  } else if (staffView === 'mobile') {
    const s = scaleFor(PHONE.w, PHONE.h, 168);
    frame = (
      <div style={{ transform: `scale(${s})`, transformOrigin: 'center center' }}>
        <window.IOSDevice>{staffInner(true)}</window.IOSDevice>
      </div>
    );
  } else {
    const s = scaleFor(DESK.w, DESK.h, 150);
    const url = auth ? (auth.role === 'admin' ? 'orthocare.app/admin' : 'orthocare.app/patients') : 'orthocare.app/login';
    frame = (
      <div style={{ transform: `scale(${s})`, transformOrigin: 'center center' }}>
        <window.ChromeWindow width={DESK.w} height={DESK.h} url={url} tabs={[{ title: "Tawfiq's Ortho Care" }]}>
          {staffInner(false)}
        </window.ChromeWindow>
      </div>
    );
  }

  const bg = surface === 'patient'
    ? 'radial-gradient(1200px 600px at 50% -10%, #143a5e 0%, #0c2238 60%)'
    : 'radial-gradient(1200px 700px at 50% -10%, #14324f 0%, #0a1c2e 65%)';

  return (
    <div style={{ position: 'fixed', inset: 0, overflow: 'hidden', background: bg }}>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{frame}</div>

      {/* caption */}
      <div style={{ position: 'absolute', top: 24, left: 0, right: 0, textAlign: 'center', color: 'rgba(255,255,255,0.5)', fontSize: 13.5, letterSpacing: 0.2, fontFamily: "'Hanken Grotesk', sans-serif", padding: '0 20px' }}>{caption}</div>

      {/* staff: mobile/desktop toggle (top center) */}
      {surface === 'staff' && (
        <div style={{ position: 'absolute', top: 52, left: '50%', transform: 'translateX(-50%)', zIndex: 65, display: 'flex', gap: 4, padding: 4, background: 'rgba(10,28,46,0.9)', border: '1px solid rgba(255,255,255,0.12)', borderRadius: 100, fontFamily: "'Hanken Grotesk', sans-serif" }}>
          {[['mobile', 'Mobile'], ['desktop', 'Desktop']].map(([v, l]) => (
            <button key={v} onClick={() => setStaffView(v)} style={{ padding: '7px 16px', cursor: 'pointer', border: 'none', borderRadius: 100, fontFamily: 'inherit', fontSize: 13, fontWeight: 600, background: staffView === v ? '#fff' : 'transparent', color: staffView === v ? '#0a1c2e' : 'rgba(255,255,255,0.7)' }}>{l}</button>
          ))}
        </div>
      )}

      {/* surface switcher (bottom) */}
      <div style={{ position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)', zIndex: 70, display: 'flex', gap: 4, padding: 5, background: 'rgba(10,28,46,0.92)', backdropFilter: 'blur(10px)', borderRadius: 100, boxShadow: '0 12px 40px rgba(0,0,0,0.4)', border: '1px solid rgba(255,255,255,0.12)', fontFamily: "'Hanken Grotesk', sans-serif" }}>
        {[
          ['patient', 'Patient phone', <svg key="a" width="17" height="17" viewBox="0 0 24 24" fill="none"><rect x="6" y="2" width="12" height="20" rx="3" stroke="currentColor" strokeWidth="2"/><path d="M10 18h4" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>],
          ['staff', 'Staff portal', <svg key="b" width="17" height="17" viewBox="0 0 24 24" fill="none"><path d="M12 3l8 4v5c0 4.5-3.2 7.8-8 9-4.8-1.2-8-4.5-8-9V7l8-4Z" stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/></svg>],
        ].map(([m, label, icon]) => {
          const on = surface === m;
          return (
            <button key={m} onClick={() => setSurface(m)} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '11px 20px', cursor: 'pointer', border: 'none', borderRadius: 100, fontFamily: 'inherit', fontSize: 14.5, fontWeight: 600, background: on ? '#fff' : 'transparent', color: on ? '#0a1c2e' : 'rgba(255,255,255,0.72)' }}>{icon}{label}</button>
          );
        })}
      </div>
    </div>
  );
}

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