// app.jsx — корень мобильного пульта: авторизация, тема, нижняя навигация,
// роутинг между экранами (Очередь / Клиенты / Расписание) и карточкой клиента.
(() => {
  const { useState, useEffect, useCallback, useRef } = React;
  const LS = { access: 'crm_access', refresh: 'crm_refresh', user: 'crm_user', theme: 'mobile_theme' };

  function lgHue(s) {
    let h = 0; s = String(s || '');
    for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) >>> 0;
    return h % 360;
  }
  function LoginAvatar({ u }) {
    const [bad, setBad] = useState(false);
    const initial = (String(u.name || '?').trim().charAt(0) || '?').toUpperCase();
    if (u.photo && !bad) {
      return <img className="mlogin-ava" alt="" src={`/api/auth/login-users/${u.ref}/photo`} onError={() => setBad(true)} />;
    }
    return <span className="mlogin-ava" style={{ '--ah': lgHue(u.ref || u.name) }}>{initial}</span>;
  }

  function getUser() {
    try { return JSON.parse(localStorage.getItem(LS.user) || 'null'); } catch { return null; }
  }

  // ── Тема ─────────────────────────────────────────────────
  function applyTheme(t) {
    document.documentElement.setAttribute('data-theme', t);
    const meta = document.querySelector('meta[name="theme-color"]');
    if (meta) meta.setAttribute('content', t === 'dark' ? '#1F1E1C' : '#F2EFE8');
  }

  // ── Login ────────────────────────────────────────────────
  function Login({ onDone }) {
    const [username, setU] = useState('');
    const [password, setP] = useState('');
    const [busy, setBusy] = useState(false);
    const [err, setErr] = useState(null);
    const [luUsers, setLuUsers] = useState([]);
    const [open, setOpen] = useState(false);
    const [sel, setSel] = useState(null); // { ref, name, photo } или null (ручной ввод)
    const comboRef = useRef(null);
    const passRef = useRef(null);

    useEffect(() => {
      window.api.auth.loginUsers()
        .then(list => setLuUsers(Array.isArray(list) ? list : []))
        .catch(() => {});
    }, []);
    useEffect(() => {
      if (!open) return;
      const onDoc = (e) => { if (comboRef.current && !comboRef.current.contains(e.target)) setOpen(false); };
      document.addEventListener('mousedown', onDoc);
      return () => document.removeEventListener('mousedown', onDoc);
    }, [open]);

    const pickUser = (u) => {
      setSel(u); setU(''); setOpen(false); setErr(null);
      setTimeout(() => passRef.current && passRef.current.focus(), 0);
    };
    const clearSel = () => { setSel(null); setU(''); setOpen(false); };

    async function submit(e) {
      e.preventDefault();
      if ((!sel && !username.trim()) || !password) { setErr('Введите логин и пароль'); return; }
      setBusy(true); setErr(null);
      try {
        const cred = sel ? { login_ref: sel.ref } : { username: username.trim() };
        const r = await window.api.auth.login({ ...cred, password });
        localStorage.setItem(LS.access, r.access);
        localStorage.setItem(LS.refresh, r.refresh);
        localStorage.setItem(LS.user, JSON.stringify(r.user));
        onDone(r.user);
      } catch (e2) {
        setErr(e2.message || 'Ошибка входа');
      } finally { setBusy(false); }
    }

    return (
      <div className="login-wrap">
        <div className="login-brand">
          <div className="login-mark">И</div>
          <div className="login-title">Импульс — пульт оператора</div>
          <div className="login-sub">Вход для сотрудников</div>
        </div>
        <form onSubmit={submit}>
          <div className="field mlogin-combo" ref={comboRef}>
            <label>Логин</label>
            {sel ? (
              <button type="button" className="input mlogin-sel" onClick={clearSel}>
                <LoginAvatar u={sel} />
                <span className="mlogin-sel-name">{sel.name}</span>
                <svg className="mlogin-x" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>
              </button>
            ) : (
              <div className="mlogin-inputwrap">
                <input className="input" autoCapitalize="none" autoCorrect="off" autoComplete="username"
                  value={username} onFocus={() => setOpen(false)} onChange={(e) => setU(e.target.value)} />
                {luUsers.length > 0 && (
                  <button type="button" className={'mlogin-chev' + (open ? ' open' : '')}
                    onClick={() => setOpen(o => !o)} aria-label="Выбрать пользователя из списка">
                    <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6"/></svg>
                  </button>
                )}
              </div>
            )}
            {open && luUsers.length > 0 && (
              <div className="mlogin-menu">
                {luUsers.map(u => (
                  <button type="button" key={u.ref} className="mlogin-opt" onClick={() => pickUser(u)}>
                    <LoginAvatar u={u} />
                    <span className="mlogin-opt-name">{u.name}</span>
                  </button>
                ))}
                <div className="mlogin-sep" />
                <button type="button" className="mlogin-opt mlogin-manual" onClick={clearSel}>
                  Ввести логин вручную
                </button>
              </div>
            )}
          </div>
          <div className="field">
            <label>Пароль</label>
            <input className="input" type="password" autoComplete="current-password" ref={passRef}
              value={password} onChange={(e) => setP(e.target.value)} />
          </div>
          {err && <div className="badge danger" style={{ display: 'block', padding: '10px 12px', marginBottom: 12 }}>{err}</div>}
          <button className="btn btn-primary" disabled={busy}>{busy ? 'Вход…' : 'Войти'}</button>
        </form>
      </div>
    );
  }

  // ── Shell (после входа) ──────────────────────────────────
  const TABS = [
    { key: 'clients', label: 'Клиенты', icon: 'users' },
    { key: 'schedule', label: 'Расписание', icon: 'calendar' },
    { key: 'subs', label: 'Абонементы', icon: 'card' },
    { key: 'payments', label: 'Оплаты', icon: 'ruble' },
    { key: 'teachers', label: 'Тренеры', icon: 'user' },
    { key: 'queue', label: 'События', icon: 'bell' },
  ];

  function Shell({ user, onLogout, theme, onToggleTheme }) {
    const [tab, setTab] = useState('clients');
    const [clientId, setClientId] = useState(null);   // карточка поверх вкладки
    const [badge, setBadge] = useState(0);

    const openClient = useCallback((id) => setClientId(id), []);
    const closeClient = useCallback(() => setClientId(null), []);

    // Счётчик «Требуют внимания» для бейджа на вкладке.
    const refreshBadge = useCallback(() => {
      window.api.operatorAlerts.get()
        .then((d) => setBadge(d.total || 0))
        .catch(() => {});
    }, []);
    useEffect(() => {
      refreshBadge();
      const t = setInterval(refreshBadge, 60000);
      return () => clearInterval(t);
    }, [refreshBadge]);

    const title = clientId ? 'Карточка клиента' : (TABS.find((t) => t.key === tab)?.label || 'Импульс');

    return (
      <div className="app">
        <div className="topbar">
          {clientId
            ? <button className="topbar-back" onClick={closeClient} aria-label="Назад"><Icon name="back" size={22} /></button>
            : <div className="login-mark" style={{ width: 32, height: 32, borderRadius: 9, fontSize: 17 }}>И</div>}
          <div className="topbar-title">{title}</div>
          {!clientId && (
            <button className="topbar-action" onClick={onToggleTheme} aria-label="Тема">
              <Icon name={theme === 'dark' ? 'sun' : 'moon'} size={20} />
            </button>
          )}
          {!clientId && (
            <button className="topbar-action" onClick={onLogout} aria-label="Выход">
              <Icon name="logout" size={20} />
            </button>
          )}
        </div>

        {clientId ? (
          <window.ClientScreen clientId={clientId} onBack={closeClient} />
        ) : (
          <>
            {tab === 'queue' && <window.QueueScreen onOpenClient={openClient} onCountChange={setBadge} />}
            {tab === 'clients' && <window.ClientsScreen onOpenClient={openClient} />}
            {tab === 'schedule' && <window.ScheduleScreen />}
            {tab === 'subs' && <window.SubscriptionsScreen />}
            {tab === 'payments' && <window.PaymentsScreen onOpenClient={openClient} />}
            {tab === 'teachers' && <window.TeachersScreen />}
          </>
        )}

        {!clientId && (
          <nav className="navbar">
            {TABS.map((t) => (
              <button key={t.key} className={'nav-tab' + (tab === t.key ? ' active' : '')}
                onClick={() => setTab(t.key)}>
                <Icon name={t.icon} size={23} className="nav-ico" />
                {t.key === 'queue' && badge > 0 && <span className="nav-badge">{badge > 99 ? '99+' : badge}</span>}
                {t.label}
              </button>
            ))}
          </nav>
        )}
      </div>
    );
  }

  // ── Установка PWA ────────────────────────────────────────
  // Chrome/Android давно не показывает баннер сам — ловим beforeinstallprompt
  // (он сохранён в window.__pwaPrompt инлайн-скриптом из index.html) и рисуем
  // свою плашку с кнопкой. iOS Safari событие не шлёт вовсе → показываем
  // инструкцию «Поделиться → На экран Домой».
  function isStandalone() {
    return window.navigator.standalone === true
      || (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches);
  }
  function InstallPrompt() {
    const [prompt, setPrompt] = useState(window.__pwaPrompt || null);
    const [dismissed, setDismissed] = useState(localStorage.getItem('mobile_install_dismissed') === '1');

    const ua = navigator.userAgent || '';
    const isIOS = /iphone|ipad|ipod/i.test(ua) && !window.MSStream;
    const isIOSSafari = isIOS && /safari/i.test(ua) && !/crios|fxios|edgios/i.test(ua);

    useEffect(() => {
      const onInstallable = () => setPrompt(window.__pwaPrompt || null);
      const onInstalled = () => { setPrompt(null); setDismissed(true); };
      window.addEventListener('pwa-installable', onInstallable);
      window.addEventListener('pwa-installed', onInstalled);
      return () => {
        window.removeEventListener('pwa-installable', onInstallable);
        window.removeEventListener('pwa-installed', onInstalled);
      };
    }, []);

    if (dismissed || isStandalone()) return null;
    // Показываем, если: Android/Chrome дал событие, либо iOS Safari (ручная установка).
    if (!prompt && !isIOSSafari) return null;

    async function install() {
      const p = window.__pwaPrompt;
      if (!p) return;
      p.prompt();
      try { await p.userChoice; } catch {}
      window.__pwaPrompt = null;
      setPrompt(null);
    }
    function close() {
      setDismissed(true);
      localStorage.setItem('mobile_install_dismissed', '1');
    }

    return (
      <div className="install-bar">
        <div className="install-ico">И</div>
        <div className="install-text">
          {prompt
            ? <><b>Установить приложение</b><span>Быстрый доступ с домашнего экрана, без браузера</span></>
            : <><b>Добавьте на экран «Домой»</b><span>Меню «Поделиться» → «На экран Домой»</span></>}
        </div>
        {prompt && <button className="btn btn-primary install-btn" onClick={install}>Установить</button>}
        <button className="install-x" onClick={close} aria-label="Скрыть"><Icon name="x" size={18} /></button>
      </div>
    );
  }

  // ── Root ─────────────────────────────────────────────────
  function App() {
    const [user, setUser] = useState(getUser());
    const [theme, setTheme] = useState(localStorage.getItem(LS.theme) || 'airy');

    useEffect(() => { applyTheme(theme); }, [theme]);

    const toggleTheme = useCallback(() => {
      setTheme((t) => {
        const next = t === 'dark' ? 'airy' : 'dark';
        localStorage.setItem(LS.theme, next);
        return next;
      });
    }, []);

    const logout = useCallback(() => {
      try { window.api.logout(); } catch {}
      localStorage.removeItem(LS.access);
      localStorage.removeItem(LS.refresh);
      localStorage.removeItem(LS.user);
      setUser(null);
    }, []);

    return (
      <>
        {user
          ? <Shell user={user} onLogout={logout} theme={theme} onToggleTheme={toggleTheme} />
          : <Login onDone={setUser} />}
        <InstallPrompt />
        <window.ToastHost />
      </>
    );
  }

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

  // Регистрация service worker (установка PWA, офлайн-старт).
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('/sw.js').catch(() => {});
    });
  }
})();
