'use strict';
/* ──────────────────────────────────────────────────────────────────
   Practice view — random / unsolved tasks trainer.
   Renders a batch of N TaskCards; once all are answered (or user
   clicks "Завершить"), shows a summary card with score + restart.
   ────────────────────────────────────────────────────────────────── */

(async function () {
  await EP.boot();
  const examKey = EP.examKey;

  const main = document.getElementById('ep-main');

  // Per-session state
  let batch        = null;     // { strategy, session_id, tasks: [...] }
  let strategy     = readStrategyFromUrl() || readPersistedStrategy() || 'random';
  let count        = readPersistedCount();
  let excludeSlugs = readPersistedExclude();   // Set<slug>
  let topicSections = null;    // { sections: [...] } — lazy-loaded
  let finalized    = false;
  const results    = new Map();   // taskId -> { isCorrect: 0|1|null, attempts: number }

  function readStrategyFromUrl() {
    const m = location.search.match(/[?&]strategy=(random|unsolved|weak)/);
    return m ? m[1] : null;
  }

  /* ── Strategy persistence (local pref) ──────────────────────── */
  function readPersistedStrategy() {
    try { return localStorage.getItem(`exam_prep_${examKey}_practice_strategy`); } catch { return null; }
  }
  function persistStrategy(s) {
    try { localStorage.setItem(`exam_prep_${examKey}_practice_strategy`, s); } catch {}
  }
  function readPersistedCount() {
    try {
      const n = Number(localStorage.getItem(`exam_prep_${examKey}_practice_count`));
      return (n >= 5 && n <= 30) ? n : 10;
    } catch { return 10; }
  }
  function persistCount(n) {
    try { localStorage.setItem(`exam_prep_${examKey}_practice_count`, String(n)); } catch {}
  }
  function readPersistedExclude() {
    try {
      const raw = localStorage.getItem(`exam_prep_${examKey}_practice_exclude`) || '';
      return new Set(raw.split(',').filter(Boolean));
    } catch { return new Set(); }
  }
  function persistExclude(set) {
    try {
      localStorage.setItem(`exam_prep_${examKey}_practice_exclude`, Array.from(set).join(','));
    } catch {}
  }

  /* ── Boot: show controls and load first batch ───────────────── */
  await loadBatch();

  /* ── Controls bar ───────────────────────────────────────────── */
  function controlsHTML() {
    const opts = [5, 10, 15, 20].map(n => `
      <option value="${n}" ${n === count ? 'selected' : ''}>${n} задач</option>`).join('');
    const excludeBadge = excludeSlugs.size
      ? `<span class="pr-exclude-count">${excludeSlugs.size}</span>` : '';
    // Exclude only applies to the difficulty-ordered random pool. Hide
    // for other strategies so users don't think it filters them too.
    const showExclude = strategy === 'random';
    return `
      <div class="pr-controls">
        <div class="pr-controls-row">
          <div class="pr-strategy">
            <button class="pr-strategy-btn ${strategy === 'random' ? 'active' : ''}" data-strat="random">
              <i data-lucide="shuffle"></i> Случайные
            </button>
            <button class="pr-strategy-btn ${strategy === 'unsolved' ? 'active' : ''}" data-strat="unsolved">
              <i data-lucide="circle-dashed"></i> Только нерешённые
            </button>
            <button class="pr-strategy-btn ${strategy === 'weak' ? 'active' : ''}" data-strat="weak"
                    title="Топ-3 темы с худшей точностью (нужно ≥3 попыток в теме)">
              <i data-lucide="target"></i> Слабые темы
            </button>
          </div>
          <div class="pr-count-pick">
            <label>Размер сессии:</label>
            <select class="pr-count-select">${opts}</select>
          </div>
          ${showExclude ? `
          <button class="ep-btn pr-exclude-btn" title="Исключить темы из пула случайных задач">
            <i data-lucide="filter-x"></i> Исключить темы ${excludeBadge}
          </button>` : ''}
          <button class="ep-btn ep-btn-primary pr-restart">
            <i data-lucide="rotate-cw"></i> Новая сессия
          </button>
        </div>
        ${strategy === 'random' ? `
          <div class="pr-difficulty-note">
            <i data-lucide="bar-chart-2"></i>
            Задачи идут по возрастанию сложности: 1-я всегда лёгкая, к концу — сложнее.
          </div>` : ''}
        <div class="pr-progress" id="pr-progress"></div>
      </div>`;
  }

  function renderProgress() {
    const el = document.getElementById('pr-progress');
    if (!el || !batch) return;
    const total      = batch.tasks.length;
    const answered   = Array.from(results.values()).filter(r => r.isCorrect != null).length;
    const correct    = Array.from(results.values()).filter(r => r.isCorrect === 1).length;
    const pct        = total ? Math.round((answered / total) * 100) : 0;
    el.innerHTML = `
      <div class="pr-progress-meta">
        <span>Прогресс сессии</span>
        <span class="pr-progress-counts">${answered}/${total} · ${correct} верно</span>
      </div>
      <div class="ep-bar"><div class="ep-bar-fill" style="width:${pct}%"></div></div>`;
  }

  /* ── Batch loading + render ─────────────────────────────────── */
  async function loadBatch() {
    finalized = false;
    results.clear();
    main.innerHTML = controlsHTML() + `
      <div class="ep-empty">
        <i data-lucide="loader-circle"></i>
        <h4>Загрузка задач…</h4>
      </div>`;
    if (window.lucide) lucide.createIcons();
    wireControls();

    try {
      const query = { count, strategy };
      if (strategy === 'random' && excludeSlugs.size) {
        query.exclude = Array.from(excludeSlugs).join(',');
      }
      batch = await EP.api.getPracticeNext(examKey, query);
    } catch (e) {
      main.querySelector('.ep-empty').outerHTML = `
        <div class="ep-empty">
          <i data-lucide="alert-triangle"></i>
          <h4>Не удалось загрузить задачи</h4>
          <p>${escapeHtml(e.message || String(e))}</p>
        </div>`;
      if (window.lucide) lucide.createIcons();
      return;
    }

    if (!batch.tasks.length) {
      main.querySelector('.ep-empty').outerHTML = `
        <div class="ep-empty">
          <i data-lucide="party-popper"></i>
          <h4>Не нашлось задач по этой стратегии</h4>
          <p>Попробуйте другую — или это знак, что вы уже всё решили.</p>
        </div>`;
      if (window.lucide) lucide.createIcons();
      return;
    }

    renderBatch();
  }

  function renderBatch() {
    // Replace empty placeholder with task list
    const empty = main.querySelector('.ep-empty');
    const taskContainer = document.createElement('div');
    taskContainer.className = 'pr-tasks';
    if (empty) empty.replaceWith(taskContainer);

    batch.tasks.forEach((task, i) => {
      results.set(task.id, { isCorrect: null, attempts: 0 });
      EP.TaskCard.render(taskContainer, task, {
        mode: 'practice',
        sessionId: batch.session_id,
        numbering: i + 1,
        onAttempt: ({ taskId, isCorrect, attempt }) => {
          if (isCorrect == null) return;          // ignore solution-only events
          const r = results.get(taskId);
          if (!r) return;
          // We record only the FIRST attempt result toward batch score.
          if (r.isCorrect == null) r.isCorrect = isCorrect;
          r.attempts = attempt || r.attempts + 1;
          renderProgress();
          maybeFinalize();
        },
      });
    });

    // Bottom: "Завершить" button (allow finalizing early)
    const finish = document.createElement('div');
    finish.className = 'pr-finish-row';
    finish.innerHTML = `
      <button class="ep-btn pr-finish-btn">
        <i data-lucide="flag"></i> Завершить и показать итог
      </button>`;
    main.appendChild(finish);
    finish.querySelector('.pr-finish-btn').onclick = () => finalize();

    renderProgress();
    if (window.lucide) lucide.createIcons();
  }

  function maybeFinalize() {
    const answered = Array.from(results.values()).filter(r => r.isCorrect != null).length;
    if (answered === batch.tasks.length && !finalized) {
      finalize();
    }
  }

  function finalize() {
    if (finalized) return;
    finalized = true;
    const total    = batch.tasks.length;
    const answered = Array.from(results.values()).filter(r => r.isCorrect != null).length;
    const correct  = Array.from(results.values()).filter(r => r.isCorrect === 1).length;
    const acc      = answered ? Math.round((correct / answered) * 100) : 0;

    const summary = document.createElement('div');
    summary.className = 'pr-summary ep-card';
    summary.innerHTML = `
      <div class="pr-summary-grid">
        <div class="pr-summary-stat">
          <div class="ep-stat-label">Решено</div>
          <div class="ep-stat-value ep-violet">${answered} / ${total}</div>
        </div>
        <div class="pr-summary-stat">
          <div class="ep-stat-label">Верно</div>
          <div class="ep-stat-value ${acc >= 70 ? 'ep-good' : 'ep-warn'}">${correct}</div>
          <div class="ep-stat-sub">${acc}% точности</div>
        </div>
        <div class="pr-summary-stat">
          <div class="ep-stat-label">Стратегия</div>
          <div class="ep-stat-value" style="font-size:1.1rem">${strategyLabel(strategy)}</div>
        </div>
      </div>
      <div class="ep-cta-row">
        <button class="ep-btn ep-btn-primary" id="pr-summary-restart">
          <i data-lucide="rotate-cw"></i> Ещё ${count} задач
        </button>
        <a class="ep-btn" href="/exam-prep/${examKey}">
          <i data-lucide="gauge"></i> На дашборд
        </a>
      </div>`;
    main.appendChild(summary);
    summary.querySelector('#pr-summary-restart').onclick = () => loadBatch();
    if (window.lucide) lucide.createIcons();
    summary.scrollIntoView({ behavior: 'smooth', block: 'start' });
  }

  /* ── Wire controls (strategy toggle, count select, restart) ── */
  function wireControls() {
    main.querySelectorAll('[data-strat]').forEach(btn => {
      btn.onclick = () => {
        if (btn.disabled) return;
        strategy = btn.dataset.strat;
        persistStrategy(strategy);
        loadBatch();
      };
    });
    const sel = main.querySelector('.pr-count-select');
    if (sel) {
      sel.onchange = () => {
        count = Number(sel.value) || 10;
        persistCount(count);
      };
    }
    const restart = main.querySelector('.pr-restart');
    if (restart) restart.onclick = () => loadBatch();

    const excludeBtn = main.querySelector('.pr-exclude-btn');
    if (excludeBtn) excludeBtn.onclick = () => openExcludeModal();
  }

  /* ── Exclude-topics modal ───────────────────────────────────── */
  async function openExcludeModal() {
    if (!topicSections) {
      try {
        topicSections = await EP.api.listTopics(examKey);
      } catch (e) {
        LS.toast?.('Не удалось загрузить темы', 'error');
        return;
      }
    }
    const sections = topicSections.sections || [];
    const sectionsHtml = sections.map(sec => {
      const items = (sec.subtopics || []).map(st => {
        const checked = excludeSlugs.has(st.slug) ? 'checked' : '';
        return `
          <label class="pr-ex-item">
            <input type="checkbox" value="${st.slug}" ${checked} />
            <span class="pr-ex-title">${escapeHtml(st.title)}</span>
            <span class="pr-ex-meta">${st.total || 0} задач</span>
          </label>`;
      }).join('');
      return `
        <div class="pr-ex-section">
          <div class="pr-ex-section-head">
            <span>${escapeHtml(sec.title)}</span>
            <button type="button" class="pr-ex-toggle-all" data-section="${sec.slug}">Все</button>
          </div>
          <div class="pr-ex-items" data-section-items="${sec.slug}">${items}</div>
        </div>`;
    }).join('');

    const body = `
      <div class="pr-ex-form">
        <p class="pr-ex-hint">Отмеченные темы не попадут в случайный пул. Сложность распределения сохраняется.</p>
        ${sectionsHtml || '<div class="pr-ex-empty">Темы не настроены</div>'}
      </div>`;

    const m = LS.modal({
      title: 'Исключить темы из пула',
      content: body,
      size: 'md',
      actions: [
        { label: 'Сбросить', onClick: () => {
            m.body.querySelectorAll('input[type="checkbox"]').forEach(c => c.checked = false);
          } },
        { label: 'Отмена', onClick: () => m.close() },
        { label: 'Применить', primary: true, onClick: () => {
            const checked = Array.from(m.body.querySelectorAll('input[type="checkbox"]:checked')).map(c => c.value);
            excludeSlugs = new Set(checked);
            persistExclude(excludeSlugs);
            m.close();
            loadBatch();
          } },
      ],
    });

    // "Все" toggle per section
    m.body.querySelectorAll('.pr-ex-toggle-all').forEach(btn => {
      btn.onclick = () => {
        const items = m.body.querySelector(`[data-section-items="${btn.dataset.section}"]`);
        if (!items) return;
        const boxes = items.querySelectorAll('input[type="checkbox"]');
        const allChecked = Array.from(boxes).every(b => b.checked);
        boxes.forEach(b => b.checked = !allChecked);
      };
    });
  }

  function escapeHtml(s) {
    return String(s || '').replace(/[&<>"']/g, c => ({ '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#39;' }[c]));
  }

  function strategyLabel(s) {
    if (s === 'unsolved') return 'Нерешённые';
    if (s === 'weak')     return 'Слабые темы';
    if (s === 'unsolved-fallback') return 'Нерешённые (fallback)';
    return 'Случайные';
  }
})();
