/* Корневое приложение портала ЛАН-ПРОЕКТ.
   Подключает реальный API: восстановление сессии, вход/выход, загрузка данных
   клиента/админа, выдача ссылок на дистрибутивы с записью в журнал.
   Режим (client/admin) задаётся window.PORTAL_MODE до загрузки этого файла. */
(function () {
  const { Button } = window.DesignSystem_219642;
  const D = window.PortalData;
  const {
    Background, Sidebar, TopBar, LoginScreen,
    Dashboard, UpdatesFeed, ProductScreen, VersionScreen, ProfileScreen,
    AdminProducts, AdminVersions, AdminLicenses, AdminUsers, AdminLog,
  } = window;
  const { useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakColor, TweakToggle } = window;

  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "accent": "#2563eb",
    "density": "comfortable",
    "radius": 16,
    "motifs": true
  }/*EDITMODE-END*/;

  function hexToRgb(hex) {
    const n = parseInt(hex.slice(1), 16);
    return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
  }
  function lighten(hex, amt) {
    const [r, g, b] = hexToRgb(hex);
    const f = (c) => Math.round(c + (255 - c) * amt);
    return `rgb(${f(r)}, ${f(g)}, ${f(b)})`;
  }
  function rgba(hex, a) { const [r, g, b] = hexToRgb(hex); return `rgba(${r}, ${g}, ${b}, ${a})`; }

  // ---- Модальное окно выдачи ссылки ----
  function DownloadModal({ data, onClose }) {
    const [copied, setCopied] = React.useState(false);
    if (!data) return null;
    const { version, product } = data;
    const lic = D.licenseFor(product.id);
    // Пропускаем только http(s)-ссылки — защита от javascript:/data: URI.
    const safeHref = /^https?:\/\//i.test(version.yadisk_url || '') ? version.yadisk_url : null;
    const copy = () => {
      navigator.clipboard && navigator.clipboard.writeText(version.yadisk_url);
      setCopied(true); setTimeout(() => setCopied(false), 1800);
    };
    return (
      <div style={{ position: 'fixed', inset: 0, zIndex: 80, display: 'grid', placeItems: 'center', padding: '24px' }}>
        <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(8,12,18,0.66)', backdropFilter: 'blur(3px)' }} />
        <div className="portal-modal" style={{ position: 'relative', width: '100%', maxWidth: '460px', background: 'var(--surface-card)', border: '1px solid var(--border-light)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', overflow: 'hidden' }}>
          <div style={{ borderTop: '2px solid var(--accent)', padding: '26px 28px 0' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: '14px' }}>
              <div style={{ width: '46px', height: '46px', borderRadius: 'var(--radius)', display: 'grid', placeItems: 'center', background: 'rgba(34,197,94,0.12)', border: '1px solid rgba(34,197,94,0.3)', color: 'var(--green-500)', fontSize: '20px' }}>
                <i className="fas fa-circle-check" />
              </div>
              <div>
                <h3 style={{ margin: 0, fontSize: '18px', fontWeight: 700, color: 'var(--text-primary)' }}>Ссылка выдана</h3>
                <div style={{ fontSize: '13px', color: 'var(--text-secondary)' }}>{product.name} · <span style={{ fontFamily: 'var(--font-mono)' }}>v{version.version}</span></div>
              </div>
            </div>
          </div>
          <div style={{ padding: '22px 28px 26px' }}>
            <div style={{ fontSize: '11px', letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--text-muted)', marginBottom: '8px' }}>Ссылка на дистрибутив (Я.Диск)</div>
            <div style={{ display: 'flex', gap: '8px', alignItems: 'center', background: 'var(--surface-base)', border: '1px solid var(--border)', borderRadius: 'var(--radius)', padding: '10px 12px', marginBottom: '18px' }}>
              <i className="fab fa-yandex" style={{ color: 'var(--accent-light)' }} />
              <span style={{ flex: 1, fontFamily: 'var(--font-mono)', fontSize: '12.5px', color: 'var(--text-secondary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{version.yadisk_url}</span>
              <button onClick={copy} title="Скопировать" style={{ background: 'transparent', border: '1px solid var(--border)', color: copied ? 'var(--green-500)' : 'var(--text-secondary)', width: '30px', height: '30px', borderRadius: '6px', cursor: 'pointer', flexShrink: 0 }}>
                <i className={copied ? 'fas fa-check' : 'far fa-copy'} style={{ fontSize: '12px' }} />
              </button>
            </div>
            <div style={{ display: 'flex', gap: '8px', fontSize: '11.5px', color: 'var(--text-muted)', lineHeight: 1.5, marginBottom: '20px' }}>
              <i className="fas fa-shield-halved" style={{ marginTop: '2px', color: 'var(--accent-light)' }} />
              <span>Выдача зафиксирована в журнале аудита: {D.formatDate(D.TODAY)}{lic ? `, лицензия ${lic.license_key}` : ''}. IP сохранён на сервере.</span>
            </div>
            <div style={{ display: 'flex', gap: '10px' }}>
              <Button variant="glass" onClick={onClose} fullWidth>Закрыть</Button>
              <Button variant="primary" href={safeHref || undefined} disabled={!safeHref} target="_blank" rel="noopener noreferrer" icon="fas fa-arrow-up-right-from-square" fullWidth>Открыть на Я.Диске</Button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  function buildCrumbs(route, nav) {
    const home = { label: 'Обзор', onClick: () => nav({ screen: 'dashboard' }) };
    switch (route.screen) {
      case 'dashboard': return [{ label: 'Обзор' }];
      case 'updates': return [{ label: 'Обновления' }];
      case 'profile': return [{ label: 'Профиль' }];
      case 'product': { const p = D.productBySlug(route.params.slug); return [home, { label: p ? p.name : '—' }]; }
      case 'version': { const v = D.versionById(route.params.id); const p = v && D.productById(v.product_id); return [home, { label: p ? p.name : '—', onClick: () => p && nav({ screen: 'product', params: { slug: p.slug } }) }, { label: v ? 'v' + v.version : '—' }]; }
      case 'admin-products': return [{ label: 'Управление' }, { label: 'Продукты' }];
      case 'admin-versions': return [{ label: 'Управление' }, { label: 'Версии' }];
      case 'admin-licenses': return [{ label: 'Управление' }, { label: 'Лицензии' }];
      case 'admin-users': return [{ label: 'Управление' }, { label: 'Пользователи' }];
      case 'admin-log': return [{ label: 'Аудит' }, { label: 'Журнал выдач' }];
      default: return [{ label: 'Обзор' }];
    }
  }

  const PORTAL_MODE = window.PORTAL_MODE === 'admin' ? 'admin' : 'client';

  // Полноэкранный лоадер на время проверки сессии / загрузки данных.
  function Loader() {
    return (
      <div style={{ position: 'fixed', inset: 0, display: 'grid', placeItems: 'center', background: 'var(--surface-base)' }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '16px' }}>
          <div style={{ width: '34px', height: '34px', borderRadius: '50%', border: '3px solid var(--border)', borderTopColor: 'var(--accent)', animation: 'portalSpin 0.8s linear infinite' }} />
          <div style={{ fontSize: '13px', color: 'var(--text-muted)', fontFamily: 'var(--font-mono)' }}>Загрузка портала…</div>
        </div>
      </div>
    );
  }

  function App() {
    const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
    const [phase, setPhase] = React.useState('loading'); // loading | login | ready
    const [role, setRole] = React.useState(null);         // 'client' | 'admin'
    const [route, setRoute] = React.useState({ screen: 'dashboard' });
    const [download, setDownload] = React.useState(null);
    const [, forceTick] = React.useReducer((x) => x + 1, 0);
    const scrollRef = React.useRef(null);

    const nav = (r) => { setRoute(r); if (scrollRef.current) scrollRef.current.scrollTop = 0; };

    const loadFor = async (r) => { if (r === 'admin') await D.loadAdmin(); else await D.loadClient(); };

    const enter = async (user) => {
      const r = user.role === 'admin' ? 'admin' : 'client';
      await loadFor(r);
      setRole(r);
      setRoute(r === 'admin' ? { screen: 'admin-products' } : { screen: 'dashboard' });
      setPhase('ready');
    };

    // Восстановление сессии при загрузке страницы.
    React.useEffect(() => {
      let alive = true;
      (async () => {
        try { const u = await D.me(); if (alive) await enter(u); }
        catch (_) { if (alive) setPhase('login'); }
      })();
      return () => { alive = false; };
    }, []);

    // Применяем Tweaks к корневым CSS-переменным.
    React.useEffect(() => {
      const root = document.documentElement;
      root.style.setProperty('--accent', t.accent);
      root.style.setProperty('--accent-light', lighten(t.accent, 0.18));
      root.style.setProperty('--accent-dark', lighten(t.accent, -0.0));
      root.style.setProperty('--accent-glow', lighten(t.accent, 0.35));
      root.style.setProperty('--accent-muted', rgba(t.accent, 0.15));
      root.style.setProperty('--accent-soft', rgba(t.accent, 0.10));
      root.style.setProperty('--border-accent', rgba(t.accent, 0.30));
      root.style.setProperty('--text-accent', lighten(t.accent, 0.18));
      root.style.setProperty('--radius-lg', t.radius + 'px');
      root.setAttribute('data-density', t.density);
    }, [t.accent, t.radius, t.density]);

    const onLogin = async (email, password) => {
      const u = await D.login(email, password);
      await enter(u);
    };

    const onLogout = async () => {
      await D.logout();
      setRole(null);
      setRoute({ screen: 'dashboard' });
      setPhase('login');
    };

    const reloadAdmin = async () => { await D.loadAdmin(); forceTick(); };
    const reloadClient = async () => { await D.loadClient(); forceTick(); };

    const onDownload = async (version, product) => {
      try {
        const url = await D.getDownloadLink(version.id);
        setDownload({ version: { ...version, yadisk_url: url }, product });
        // Обновляем историю загрузок (профиль), чтобы выдача сразу была видна.
        if (role === 'client') { try { await D.loadClient(); forceTick(); } catch (_) {} }
      } catch (e) {
        window.alert(e && e.code === 'no_access'
          ? 'Эта версия недоступна по вашей лицензии (право на обновления не покрывает дату релиза).'
          : 'Не удалось получить ссылку. Попробуйте позже.');
      }
    };

    const panel = (
      <TweaksPanel>
        <TweakSection label="Акцент" />
        <TweakColor label="Цвет акцента" value={t.accent}
          options={['#2563eb', '#0ea5e9', '#4f46e5', '#0891b2']}
          onChange={(v) => setTweak('accent', v)} />
        <TweakSection label="Макет" />
        <TweakRadio label="Плотность" value={t.density}
          options={[{ value: 'comfortable', label: 'Просторно' }, { value: 'compact', label: 'Компактно' }]}
          onChange={(v) => setTweak('density', v)} />
        <TweakRadio label="Скругление" value={t.radius}
          options={[{ value: 8, label: 'Чёткое' }, { value: 12, label: 'Среднее' }, { value: 16, label: 'Мягкое' }]}
          onChange={(v) => setTweak('radius', v)} />
        <TweakSection label="Оформление" />
        <TweakToggle label="Фоновый паттерн" value={t.motifs} onChange={(v) => setTweak('motifs', v)} />
      </TweaksPanel>
    );

    if (phase === 'loading') return <React.Fragment><Loader />{panel}</React.Fragment>;

    if (phase === 'login') {
      return (
        <React.Fragment>
          <LoginScreen variant={PORTAL_MODE} onLogin={onLogin} />
          {panel}
        </React.Fragment>
      );
    }

    const user = D.currentUser || {};
    const updatesCount = (() => {
      if (role !== 'client') return undefined;
      let n = 0;
      D.products.forEach((p) => { const l = D.licenseFor(p.id); D.versionsFor(p.id).forEach((v) => { if (D.versionAvailable(l, v)) n++; }); });
      return n;
    })();

    // Уведомления выводятся из реальных данных (не статичный счётчик).
    const notifications = (() => {
      const out = [];
      if (role === 'client') {
        D.licenses.forEach((l) => {
          const st = D.updatesStatus(l.updates_until);
          const p = D.productById(l.product_id);
          if (!p) return;
          if (st.code === 'expired') out.push({ id: 'exp-' + l.id, icon: 'fas fa-triangle-exclamation', tone: 'danger', title: `Право на обновления по «${p.name}» истекло ${D.formatDate(l.updates_until)}`, onClick: () => nav({ screen: 'product', params: { slug: p.slug } }) });
          else if (st.code === 'soon') out.push({ id: 'soon-' + l.id, icon: 'fas fa-clock', tone: 'warning', title: `Право на обновления по «${p.name}» истекает ${D.formatDate(l.updates_until)}`, onClick: () => nav({ screen: 'product', params: { slug: p.slug } }) });
        });
        D.versions.forEach((v) => {
          if (v.critical && D.versionAvailable(D.licenseFor(v.product_id), v)) {
            const p = D.productById(v.product_id);
            out.push({ id: 'crit-' + v.id, icon: 'fas fa-circle-arrow-up', tone: 'accent', title: `Доступно важное обновление: ${p ? p.name : ''} v${v.version}`, onClick: () => nav({ screen: 'version', params: { id: v.id } }) });
          }
        });
      } else {
        D.adminLicenses.forEach((l) => {
          const st = D.updatesStatus(l.updates_until);
          if (st.code === 'expired') out.push({ id: 'aexp-' + l.id, icon: 'fas fa-triangle-exclamation', tone: 'danger', title: `Лицензия ${l.key} (${l.user}): право на обновления истекло`, onClick: () => nav({ screen: 'admin-licenses' }) });
          else if (st.code === 'soon') out.push({ id: 'asoon-' + l.id, icon: 'fas fa-clock', tone: 'warning', title: `Лицензия ${l.key} (${l.user}): обновления истекают ${D.formatDate(l.updates_until)}`, onClick: () => nav({ screen: 'admin-licenses' }) });
        });
      }
      return out;
    })();

    let screen = null;
    switch (route.screen) {
      case 'dashboard': screen = <Dashboard nav={nav} onDownload={onDownload} user={user} />; break;
      case 'updates': screen = <UpdatesFeed nav={nav} onDownload={onDownload} />; break;
      case 'product': screen = <ProductScreen slug={route.params.slug} nav={nav} onDownload={onDownload} />; break;
      case 'version': screen = <VersionScreen id={route.params.id} nav={nav} onDownload={onDownload} />; break;
      case 'profile': screen = <ProfileScreen user={user} reload={reloadClient} />; break;
      case 'admin-products': screen = <AdminProducts reload={reloadAdmin} />; break;
      case 'admin-versions': screen = <AdminVersions reload={reloadAdmin} />; break;
      case 'admin-licenses': screen = <AdminLicenses reload={reloadAdmin} />; break;
      case 'admin-users': screen = <AdminUsers reload={reloadAdmin} />; break;
      case 'admin-log': screen = <AdminLog />; break;
      default: screen = role === 'admin' ? <AdminProducts reload={reloadAdmin} /> : <Dashboard nav={nav} onDownload={onDownload} user={user} />;
    }

    return (
      <React.Fragment>
        <Background dots={t.motifs} />
        <div style={{ position: 'relative', zIndex: 1 }}>
          <Sidebar route={route} nav={nav} role={role} user={user} updatesCount={updatesCount} onLogout={onLogout} />
          <div style={{ marginLeft: '264px', minHeight: '100vh' }}>
            <TopBar crumbs={buildCrumbs(route, nav)} notifications={notifications} />
            <main ref={scrollRef} className="portal-main" style={{ padding: '32px 40px 64px', maxWidth: '1200px' }}>
              <div className="portal-screen" key={route.screen + JSON.stringify(route.params || {})}>{screen}</div>
            </main>
          </div>
        </div>
        {download && <DownloadModal data={download} onClose={() => setDownload(null)} />}
        {panel}
      </React.Fragment>
    );
  }

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