// app.jsx — корневой компонент

const LoadingScreen = ({ error, onRetry }) => (
  <div style={{
    display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
    minHeight: '100vh', fontFamily: 'var(--font-ui, Geist, sans-serif)', gap: 16,
  }}>
    {error ? (
      <>
        <p style={{ color: 'var(--coral, #e85d4c)', maxWidth: 420, textAlign: 'center' }}>{error}</p>
        <button className="btn btn-primary" onClick={onRetry}>Повторить</button>
      </>
    ) : (
      <>
        <div style={{ width: 32, height: 32, border: '3px solid var(--border, #e5e5e5)', borderTopColor: 'var(--accent, #2563eb)', borderRadius: '50%', animation: 'spin 0.8s linear infinite' }} />
        <p style={{ color: 'var(--text-2, #666)' }}>Загрузка базы знаний…</p>
        <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
      </>
    )}
  </div>
);

const VIEW_TITLES = {
  home: 'Главная',
  database: 'База знаний',
  tests: 'Тесты',
  org: 'Структура организации',
  panel: 'Панель управления',
  settings: 'Настройки',
};

const Nav = window.NavStore || {
  loadView: () => 'home',
  loadKbNav: () => null,
  loadSettingsTab: () => 'profile',
  loadTestRoute: () => ({ screen: 'list', filter: 'all' }),
  loadOpenArticle: () => null,
  persistView: () => {},
  persistKbNav: () => {},
  persistSettingsTab: () => {},
  persistTestRoute: () => {},
  persistOpenArticle: () => {},
  clearOpenArticle: () => {},
  clearTestRoute: () => {},
  clearOnLeaveSection: () => {},
};

const AppShell = () => {
  const [view, setView] = React.useState(() => Nav.loadView());
  const [openArticle, setOpenArticle] = React.useState(null);
  const [editing, setEditing] = React.useState(null);
  const [saving, setSaving] = React.useState(false);
  const [articleOrigin, setArticleOrigin] = React.useState(null);
  const [kbNav, setKbNav] = React.useState(() => Nav.loadKbNav());
  const [settingsTab, setSettingsTab] = React.useState(() => Nav.loadSettingsTab());
  const [testRoute, setTestRoute] = React.useState(null);
  const [testLock, setTestLock] = React.useState(null);
  const [revision, bumpRevision] = React.useReducer((n) => n + 1, 0);

  React.useEffect(() => {
    const stored = Nav.loadOpenArticle();
    if (!stored?.articleId) return;
    const article = window.findArticle(stored.articleId);
    if (article && window.KB.canViewArticle(article)) {
      setOpenArticle(article);
      setArticleOrigin(stored.origin || 'structure');
    } else {
      Nav.clearOpenArticle();
    }
  }, []);

  React.useEffect(() => {
    (async () => {
      const active = await window.KB.getActiveTestAttempt?.();
      if (!active) {
        window.KB.clearTestLock();
        setTestLock(null);
        return;
      }
      setTestLock({
        inProgress: true,
        testId: active.testId,
        articleId: active.articleId,
        attemptId: active.attemptId,
      });
      window.KB.setTestLock({
        inProgress: true,
        testId: active.testId,
        articleId: active.articleId,
        attemptId: active.attemptId,
      });
    })();
  }, []);

  const navigate = (v) => {
    setView(v);
    setOpenArticle(null);
    setEditing(null);
    setArticleOrigin(null);
    setTestRoute(null);
    Nav.persistView(v);
    Nav.clearOnLeaveSection(v);
    if (v !== 'database') setKbNav(null);
  };

  const navigateSettings = (tab = 'profile') => {
    setSettingsTab(tab);
    Nav.persistSettingsTab(tab);
    setView('settings');
    setOpenArticle(null);
    setEditing(null);
    setArticleOrigin(null);
    setKbNav(null);
    Nav.persistView('settings');
    Nav.clearOpenArticle();
    Nav.clearTestRoute();
  };

  const navigateKb = (tagFilter = '') => {
    const nav = tagFilter ? {
      selectedId: null,
      specialView: null,
      openIds: { __root: true },
      localSearch: '',
      statusFilter: '',
      tagFilter,
      sort: 'updated',
      viewMode: 'grid',
    } : null;
    setKbNav(nav);
    Nav.persistKbNav(nav);
    setOpenArticle(null);
    setEditing(null);
    setArticleOrigin(null);
    Nav.clearOpenArticle();
    setView('database');
    Nav.persistView('database');
    Nav.clearTestRoute();
  };

  const handleNavigate = async (v) => {
    if (testLock?.inProgress) {
      await window.UI.alert({
        title: 'Тест не завершён',
        message: 'Во время прохождения нельзя перейти в другой раздел. Завершите тест или дождитесь окончания времени.',
        icon: 'quiz',
      });
      return;
    }
    if (v === 'settings') navigateSettings('profile');
    else navigate(v);
  };

  const openArticleView = async (article, origin = 'structure', navSnapshot = null) => {
    if (window.KB.isArticleLockedByTest?.(article.id)) {
      await window.UI.alert({
        title: 'Статья недоступна',
        message: 'Эта статья скрыта, пока вы проходите связанный с ней тест.',
        icon: 'quiz',
      });
      return;
    }
    if (!window.KB.canViewArticle(article)) {
      await window.UI.alert({
        title: 'Нет доступа',
        message: 'У вас нет прав для просмотра этой статьи.',
      });
      return;
    }
    if (navSnapshot) {
      setKbNav(navSnapshot);
      Nav.persistKbNav(navSnapshot);
    }
    window.KB.trackRecent(article.id);
    setOpenArticle(article);
    setArticleOrigin(origin);
    Nav.persistOpenArticle(article.id, origin);
  };

  const handleSearchOpenArticle = (article) => {
    openArticleView(article, view === 'home' ? 'home' : 'structure');
    setView('database');
    Nav.persistView('database');
  };

  const handleKbNavChange = React.useCallback((nav) => {
    setKbNav(nav);
    Nav.persistKbNav(nav);
  }, []);

  const setTestRoutePersisted = (route) => {
    setTestRoute(route);
    Nav.persistTestRoute(route);
  };

  const startCreate = (sectionId = null) => {
    if (!window.KB.can('kbArticles', 'edit')) return;
    setEditing(sectionId ? { section: sectionId } : {});
  };

  const openTestEditor = (article) => {
    const route = { screen: 'edit', articleId: article.id };
    setTestRoutePersisted(route);
    setView('tests');
    setOpenArticle(null);
    setEditing(null);
    Nav.clearOpenArticle();
    Nav.persistView('tests');
  };

  const openTestEditorExisting = (test) => {
    const route = { screen: 'edit', testId: test.id, articleId: test.articleId };
    setTestRoutePersisted(route);
    setView('tests');
    setOpenArticle(null);
    setEditing(null);
    Nav.clearOpenArticle();
    Nav.persistView('tests');
  };

  const openTestTake = (test, autoStart = false) => {
    const route = {
      screen: 'take',
      testId: test.id,
      articleId: test.articleId,
      autoStart,
      resume: autoStart,
    };
    setTestRoutePersisted(route);
    setView('tests');
    setOpenArticle(null);
    setEditing(null);
    Nav.clearOpenArticle();
    Nav.persistView('tests');
  };

  const handleTestBackToArticle = async (articleId) => {
    const article = window.findArticle(articleId);
    Nav.clearTestRoute();
    setTestRoute(null);
    if (!article) {
      navigate('database');
      return;
    }
    await openArticleView(article, 'structure');
    setView('database');
    Nav.persistView('database');
  };

  const handleSave = async (articleData, opts = {}) => {
    setSaving(true);
    try {
      const saved = await window.KB.saveArticle(articleData);
      setEditing(null);
      bumpRevision();
      if (opts.createTest) {
        await openTestEditor(saved);
        return saved;
      }
      setOpenArticle(saved);
      setView('database');
      setArticleOrigin('structure');
      Nav.persistView('database');
      Nav.persistOpenArticle(saved.id, 'structure');
      return saved;
    } catch (err) {
      await window.UI.alert({ title: 'Ошибка сохранения', message: err.message });
    } finally {
      setSaving(false);
    }
  };

  const closeArticle = () => {
    const origin = articleOrigin;
    setOpenArticle(null);
    setArticleOrigin(null);
    Nav.clearOpenArticle();
    const nextView = origin === 'home' ? 'home' : 'database';
    setView(nextView);
    Nav.persistView(nextView);
    window.KB.loadInteractionsMe?.().then(() => bumpRevision());
  };
  let mainContent;
  let crumbs = [];

  if (openArticle) {
    const sectionPath = window.getSectionPath(openArticle.section);
    crumbs = [
      { label: 'База знаний', onClick: closeArticle },
      ...sectionPath.map((s) => ({ label: s.name, onClick: closeArticle })),
      { label: openArticle.title, current: true },
    ].filter(Boolean);
    mainContent = (
      <ArticleDetail
        article={openArticle}
        onBack={closeArticle}
        backLabel="Назад к структуре"
        onEdit={() => setEditing(openArticle)}
        onTakeTest={(test) => openTestTake(test, true)}
        onArticleChange={(a) => setOpenArticle(a)}
        onOpenArticle={(a) => openArticleView(a, articleOrigin)}
        onBookmarksChange={bumpRevision}
      />
    );
  } else if (view === 'home') {
    crumbs = ['WYSH', 'Главная'];
    mainContent = (
      <KbHomeView
        refreshKey={revision}
        onOpenArticle={(a) => openArticleView(a, 'home')}
        onCreate={() => startCreate()}
        onNavigateKb={() => navigateKb('')}
        onTagClick={(tagId) => navigateKb(tagId)}
      />
    );
  } else if (view === 'database') {
    crumbs = ['WYSH', 'База знаний'];
    mainContent = (
      <KbStructureView
        restoredNav={kbNav}
        refreshKey={revision}
        onNavChange={handleKbNavChange}
        onOpenArticle={openArticleView}
        onCreate={startCreate}
        onEdit={(a) => setEditing(a)}
        onRefresh={bumpRevision}
      />
    );
  } else if (view === 'tests') {
    crumbs = ['WYSH', 'Тесты'];
    mainContent = (
      <TestsView
        initialRoute={testRoute}
        onRouteClear={() => setTestRoute(null)}
        onBackToArticle={handleTestBackToArticle}
        onCreateTest={openTestEditor}
        onTestLockChange={setTestLock}
      />
    );
  } else if (view === 'org') {
    mainContent = (
      <OrgView
        onOpenSettings={navigateSettings}
        onNavigateKb={() => navigate('database')}
        refreshKey={revision}
        onRefresh={bumpRevision}
      />
    );
  } else if (view === 'settings') {
    crumbs = ['WYSH', 'Настройки'];
    mainContent = (
      <SettingsView
        initialTab={settingsTab}
        onTabChange={(tab) => {
          setSettingsTab(tab);
          Nav.persistSettingsTab(tab);
        }}
        onRefresh={bumpRevision}
      />
    );
  }

  if (editing) {
    return (
      <div className="app app--editor">
        <EditorView sourceArticle={editing.id ? editing : null} saving={saving}
          defaultSection={editing.section || null}
          onBack={() => setEditing(null)} onSave={handleSave} />
      </div>
    );
  }

  return (
    <div className="app">
      <Sidebar
        activeView={view}
        onNavigate={handleNavigate}
        refreshKey={revision}
      />
      <div className="main-area">
        {(view !== 'database' && view !== 'org' || openArticle) && (
          <Topbar
            crumbs={crumbs}
            action={view !== 'database' && view !== 'org' && !openArticle && window.KB.can('kbArticles', 'edit') ? 'Создать' : null}
            onAction={() => startCreate()}
            onOpenArticle={handleSearchOpenArticle}
          />
        )}
        <div className={`content${
          (view === 'database' || view === 'org') && !openArticle
            ? ` content--${view === 'database' ? 'kb' : 'org'}-full`
            : ''
        }`}>{mainContent}</div>
      </div>
    </div>
  );
};

const App = () => {
  const [ready, setReady] = React.useState(false);
  const [authenticated, setAuthenticated] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [authChecking, setAuthChecking] = React.useState(true);

  const load = React.useCallback(async () => {
    setError(null);
    setReady(false);
    try {
      await window.KB.loadAll();
      setAuthenticated(true);
      setReady(true);
    } catch (err) {
      if (err.status === 401) {
        setAuthenticated(false);
        setReady(false);
      } else {
        setError(err.message || 'Не удалось загрузить данные');
      }
    }
  }, []);

  React.useEffect(() => {
    (async () => {
      setAuthChecking(true);
      const user = await window.KB.checkSession();
      if (user) {
        await load();
      } else {
        setAuthenticated(false);
      }
      setAuthChecking(false);
    })();
  }, [load]);

  const handleLoginSuccess = async () => {
    setError(null);
    await load();
    setAuthenticated(true);
  };

  if (authChecking) return <LoadingScreen />;
  if (!authenticated) {
    return (
      <>
        <LoginView onSuccess={handleLoginSuccess} error={error} />
        <DialogHost />
      </>
    );
  }
  if (!ready) return <LoadingScreen error={error} onRetry={load} />;
  return (
    <>
      <AppShell />
      <DialogHost />
    </>
  );
};

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