'use strict';
/* ──────────────────────────────────────────────────────────────────
   Dashboard view — landing screen of /exam-prep/:examKey
   F1: track info + global counts + cumulative progress
   F4: streak, last attempts, 7d accuracy, activity heatmap, recent mocks
   ────────────────────────────────────────────────────────────────── */

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

  const main = document.getElementById('ep-main');
  if (!info?.track) {
    main.innerHTML = `<div class="ep-empty">
      <i data-lucide="alert-triangle"></i>
      <h4>Не удалось загрузить данные экзамена</h4>
      <p>Проверьте, что миграция применена и трек math9 включён.</p>
    </div>`;
    if (window.lucide) lucide.createIcons();
    return;
  }

  const { track, counts, progress } = info;
  const solvedPct = counts.total
    ? Math.round((progress.tasks_solved / counts.total) * 100)
    : 0;
  const accAll = progress.total_attempts
    ? Math.round((progress.correct_attempts / progress.total_attempts) * 100)
    : null;

  // Fetch F4 live aggregates + F10 plan in parallel with rendering shell.
  const dashPromise = EP.api.getDashboard(track.exam_key).catch(() => null);
  const planPromise = EP.api.getPlan(track.exam_key).catch(() => null);

  main.innerHTML = `
    <div class="ep-stats" id="dh-top-stats">
      <div class="ep-stat">
        <div class="ep-stat-label">Решено задач</div>
        <div class="ep-stat-value ep-violet">${progress.tasks_solved} <span style="font-size:.7em;color:var(--text-3);font-weight:600">/ ${counts.total}</span></div>
        <div class="ep-bar"><div class="ep-bar-fill" style="width:${solvedPct}%"></div></div>
        <div class="ep-stat-sub">${solvedPct}% от банка</div>
      </div>
      <div class="ep-stat">
        <div class="ep-stat-label">Точность (всё время)</div>
        <div class="ep-stat-value ${accAll == null ? '' : accAll >= 70 ? 'ep-good' : 'ep-warn'}">${accAll == null ? '—' : accAll + '%'}</div>
        <div class="ep-stat-sub">${progress.correct_attempts} верно из ${progress.total_attempts} попыток</div>
      </div>
      <div class="ep-stat" id="dh-streak"><div class="ep-stat-label">Серия дней</div><div class="ep-stat-value"><span class="ep-skel" style="width:42px;height:1em">&nbsp;</span></div></div>
      <div class="ep-stat" id="dh-acc7"><div class="ep-stat-label">Точность 7 дней</div><div class="ep-stat-value"><span class="ep-skel" style="width:42px;height:1em">&nbsp;</span></div></div>
    </div>

    <div class="ep-card">
      <h3>С чего начать</h3>
      <div class="ep-card-hint">${escapeHtml(stripTags(track.intro_html || ''))}</div>
      <div class="ep-cta-row">
        <a class="ep-btn ep-btn-primary" href="/exam-prep/${track.exam_key}/practice">
          <i data-lucide="play"></i> Тренировка
        </a>
        <a class="ep-btn" href="/exam-prep/${track.exam_key}/variants">
          <i data-lucide="layout-grid"></i> Все варианты
        </a>
        <a class="ep-btn" href="/exam-prep/${track.exam_key}/mock">
          <i data-lucide="timer"></i> Пробный экзамен
        </a>
      </div>
    </div>

    <div class="ep-card" id="dh-plan"><div class="ep-empty" style="padding:24px"><span class="ep-skel" style="width:200px;height:1em">&nbsp;</span></div></div>

    <div class="dh-row">
      <div class="ep-card dh-recent">
        <h3>Последние попытки</h3>
        <div id="dh-recent-list" class="dh-recent-list"><div class="ep-empty" style="padding:24px"><span class="ep-skel" style="width:200px;height:1em">&nbsp;</span></div></div>
      </div>
      <div class="ep-card dh-heatmap-card">
        <h3>Активность · 28 дней</h3>
        <div id="dh-heatmap"><div class="ep-empty" style="padding:24px"><span class="ep-skel" style="width:200px;height:1em">&nbsp;</span></div></div>
      </div>
    </div>

    <div class="ep-card" id="dh-mocks">
      <h3>Пробники</h3>
      <div id="dh-mocks-list"><div class="ep-empty" style="padding:24px"><span class="ep-skel" style="width:200px;height:1em">&nbsp;</span></div></div>
    </div>

    <div class="ep-card">
      <h3>Банк задач</h3>
      <div class="ep-card-hint">Всего ${counts.total} задач в ${track.variants_count} вариантах.</div>
      <div class="ep-stats" style="margin-bottom:0">
        <div class="ep-stat">
          <div class="ep-stat-label">Тестовая часть (А)</div>
          <div class="ep-stat-value">${counts.mc}</div>
          <div class="ep-stat-sub">выбор варианта а–д</div>
        </div>
        <div class="ep-stat">
          <div class="ep-stat-label">Краткий ответ</div>
          <div class="ep-stat-value">${counts.open}</div>
          <div class="ep-stat-sub">число / дробь / пара</div>
        </div>
        <div class="ep-stat">
          <div class="ep-stat-label">Развёрнутые</div>
          <div class="ep-stat-value">${counts.long}</div>
          <div class="ep-stat-sub">выражения, графики</div>
        </div>
      </div>
    </div>

    <div class="ep-card" id="dh-weak">
      <h3>Слабые темы</h3>
      <div id="dh-weak-list"><div class="ep-empty" style="padding:20px"><span class="ep-skel" style="width:200px;height:1em">&nbsp;</span></div></div>
    </div>
  `;

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

  // Stitch in live aggregates once they arrive.
  const dash = await dashPromise;
  if (dash) {
    renderStreak(dash.streak);
    renderAcc7(dash.accuracy_7d);
    renderRecent(dash.recent_attempts, track.exam_key);
    renderHeatmap(dash.heatmap);
    renderMocks(dash.recent_mocks, track.exam_key);
    renderWeakTopics(dash.weak_topics || [], track.exam_key);
    if (window.lucide) lucide.createIcons();
  }

  // F10: plan widget
  const planPayload = await planPromise;
  renderPlanWidget(track.exam_key, planPayload?.plan || null);
  if (window.lucide) lucide.createIcons();
})();

/* ════════════════════════════════════════════════════════════════
   Widgets
   ════════════════════════════════════════════════════════════════ */

function renderStreak(streak) {
  const el = document.getElementById('dh-streak');
  if (!el) return;
  const label = streak === 0 ? 'Нет серии'
              : streak === 1 ? '1 день подряд'
              : `${streak} ${pluralRu(streak, ['день', 'дня', 'дней'])} подряд`;
  el.innerHTML = `
    <div class="ep-stat-label">Серия</div>
    <div class="ep-stat-value ${streak >= 3 ? 'ep-good' : ''}">${streak}</div>
    <div class="ep-stat-sub">${label}${streak >= 3 ? ' · так держать!' : ''}</div>`;
}

function renderAcc7(a) {
  const el = document.getElementById('dh-acc7');
  if (!el) return;
  const valClass = a.pct == null ? '' : a.pct >= 70 ? 'ep-good' : 'ep-warn';
  el.innerHTML = `
    <div class="ep-stat-label">Точность 7 дней</div>
    <div class="ep-stat-value ${valClass}">${a.pct == null ? '—' : a.pct + '%'}</div>
    <div class="ep-stat-sub">${a.correct} верно из ${a.attempts} попыток</div>`;
}

function renderRecent(items, examKey) {
  const el = document.getElementById('dh-recent-list');
  if (!el) return;
  if (!items.length) {
    el.innerHTML = `<div class="ep-empty" style="padding:20px">
      <i data-lucide="hourglass"></i>
      <p>Ещё нет попыток. Откройте <a href="/exam-prep/${examKey}/practice" style="color:var(--violet)">тренажёр</a>.</p>
    </div>`;
    return;
  }
  el.innerHTML = items.map(it => {
    const mark = it.is_correct === 1 ? '<span class="dh-mark dh-mark-ok">✓</span>'
               : it.is_correct === 0 ? '<span class="dh-mark dh-mark-bad">✗</span>'
               : it.solution_viewed   ? '<span class="dh-mark dh-mark-view">i</span>'
               : '<span class="dh-mark dh-mark-pending">·</span>';
    const when = relativeTime(it.created_at);
    const modeLabel = it.mode === 'mock' ? 'Пробник'
                    : it.mode === 'variant' ? 'Вариант'
                    : it.mode === 'practice' ? 'Тренажёр'
                    : it.mode === 'topic'    ? 'Тема'
                    : '';
    const variantBadge = it.variant != null
      ? `<a class="dh-recent-loc" href="/exam-prep/${examKey}/variants?v=${it.variant}" title="Открыть вариант ${it.variant}">В${it.variant}·№${it.task_idx}</a>`
      : `<span class="dh-recent-loc">№${it.task_idx}</span>`;
    return `<div class="dh-recent-item">
      ${mark}
      ${variantBadge}
      <div class="dh-recent-preview">${escapeHtml(it.preview)}</div>
      <div class="dh-recent-meta"><span class="dh-mode">${modeLabel}</span><span class="dh-time">${when}</span></div>
    </div>`;
  }).join('');
}

function renderHeatmap(items) {
  const el = document.getElementById('dh-heatmap');
  if (!el) return;
  // Build 28 cells ending today.
  const byDay = new Map(items.map(d => [d.day, d]));
  const cells = [];
  const today = new Date();
  for (let i = 27; i >= 0; i--) {
    const d = new Date(today);
    d.setUTCDate(today.getUTCDate() - i);
    const key = toIsoDate(d);
    const v = byDay.get(key);
    const a = v ? v.attempts : 0;
    let lvl = 0;
    if (a >= 1)  lvl = 1;
    if (a >= 5)  lvl = 2;
    if (a >= 12) lvl = 3;
    if (a >= 25) lvl = 4;
    const tip = v ? `${key}: ${v.attempts} попыток, ${v.correct} верно` : `${key}: 0`;
    cells.push(`<div class="dh-cell dh-l${lvl}" title="${tip}"></div>`);
  }
  el.innerHTML = `
    <div class="dh-heatmap">${cells.join('')}</div>
    <div class="dh-heatmap-legend">
      <span>меньше</span>
      <span class="dh-cell dh-l0"></span>
      <span class="dh-cell dh-l1"></span>
      <span class="dh-cell dh-l2"></span>
      <span class="dh-cell dh-l3"></span>
      <span class="dh-cell dh-l4"></span>
      <span>больше</span>
    </div>`;
}

/* ─── Plan widget (F10) ──────────────────────────────────────── */

function renderPlanWidget(examKey, plan) {
  const el = document.getElementById('dh-plan');
  if (!el) return;

  if (!plan) {
    el.innerHTML = `
      <h3>План подготовки</h3>
      <div class="ep-card-hint">Укажите дату экзамена — посчитаем, сколько задач нужно делать в день, чтобы успеть.</div>
      <div class="ep-cta-row">
        <button class="ep-btn ep-btn-primary" id="dh-plan-create">
          <i data-lucide="calendar-plus"></i> Создать план
        </button>
      </div>`;
    el.querySelector('#dh-plan-create').onclick = () => openPlanModal(examKey, null);
    return;
  }

  const daysLeft = plan.days_left;
  const tasksLeft = plan.tasks_left;
  const tgt = plan.daily_target || 10;
  const doneToday = plan.today.solved;
  const pctToday = tgt ? Math.min(100, Math.round((doneToday / tgt) * 100)) : 0;

  const daysClass = daysLeft <= 7 ? 'ep-warn' : daysLeft <= 30 ? 'ep-violet' : '';
  const daysLabel = daysLeft < 0
    ? `${Math.abs(daysLeft)} ${pluralRu(Math.abs(daysLeft), ['день','дня','дней'])} назад`
    : daysLeft === 0
      ? 'сегодня экзамен'
      : `${daysLeft} ${pluralRu(daysLeft, ['день','дня','дней'])}`;
  const examDateFmt = formatRuDate(plan.exam_date);
  const expired = daysLeft < 0;

  el.innerHTML = `
    <div class="dh-plan-head">
      <h3>План подготовки</h3>
      <button class="dh-plan-edit" id="dh-plan-edit" title="Изменить план">
        <i data-lucide="pencil"></i>
      </button>
    </div>
    <div class="dh-plan-grid">
      <div class="dh-plan-stat">
        <div class="ep-stat-label">До экзамена</div>
        <div class="ep-stat-value ${daysClass}">${daysLeft < 0 ? '—' : daysLeft}</div>
        <div class="ep-stat-sub">${daysLabel} · ${examDateFmt}</div>
      </div>
      <div class="dh-plan-stat">
        <div class="ep-stat-label">Сегодня</div>
        <div class="ep-stat-value ${doneToday >= tgt ? 'ep-good' : ''}">${doneToday} <span style="font-size:.7em;color:var(--text-3);font-weight:600">/ ${tgt}</span></div>
        <div class="ep-bar"><div class="ep-bar-fill" style="width:${pctToday}%"></div></div>
        <div class="ep-stat-sub">${doneToday >= tgt ? 'цель на сегодня выполнена!' : `осталось ${tgt - doneToday}`}</div>
      </div>
      <div class="dh-plan-stat">
        <div class="ep-stat-label">Осталось задач</div>
        <div class="ep-stat-value">${tasksLeft}</div>
        <div class="ep-stat-sub">${daysLeft > 0 ? `~${Math.ceil(tasksLeft / daysLeft)} в день, чтобы успеть` : 'дата прошла'}</div>
      </div>
    </div>
    ${expired ? `<div class="dh-plan-expired">Дата экзамена в прошлом. Перенесите план или удалите его.</div>` : ''}
    <div class="ep-cta-row" style="margin-top:14px">
      <a class="ep-btn ep-btn-primary" href="/exam-prep/${examKey}/practice">
        <i data-lucide="play"></i> Сделать ${Math.max(1, tgt - doneToday)} задач сейчас
      </a>
    </div>`;
  el.querySelector('#dh-plan-edit').onclick = () => openPlanModal(examKey, plan);
}

function openPlanModal(examKey, plan) {
  const today = toIsoDate(new Date());
  const examDate = plan?.exam_date || addDaysIso(today, 60);   // default: 2 months out
  const dailyTarget = plan?.daily_target || 10;

  const body = `
    <div class="dh-plan-form">
      <div class="dh-plan-field">
        <label>Дата экзамена</label>
        <input type="date" id="dh-plan-date" value="${examDate}" min="${today}" class="dh-plan-input" />
      </div>
      <div class="dh-plan-field">
        <label>Задач в день (5–50)</label>
        <input type="number" id="dh-plan-target" value="${dailyTarget}" min="5" max="50" class="dh-plan-input" />
        <div class="dh-plan-hint">Если оставить пусто или вне диапазона — посчитаем автоматом.</div>
      </div>
      <div class="dh-plan-field" id="dh-plan-derived"></div>
    </div>`;

  const actions = [
    { label: 'Отмена', onClick: () => m.close() },
  ];
  if (plan) {
    actions.push({
      label: 'Удалить план',
      onClick: async () => {
        if (!confirm('Удалить план? Прогресс сохранится.')) return;
        try {
          await EP.api.deletePlan(examKey);
          m.close();
          location.reload();
        } catch (e) {
          m.setError(`Не удалось удалить: ${e.message || e}`);
        }
      },
    });
  }
  actions.push({
    label: plan ? 'Сохранить' : 'Создать план',
    primary: true,
    onClick: async () => {
      const date = m.body.querySelector('#dh-plan-date').value;
      const target = Number(m.body.querySelector('#dh-plan-target').value) || 10;
      if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
        m.setError('Введите дату экзамена');
        return;
      }
      try {
        await EP.api.savePlan(examKey, {
          exam_date: date,
          daily_target: Math.max(5, Math.min(50, target)),
        });
        m.close();
        location.reload();
      } catch (e) {
        m.setError(`Не удалось сохранить: ${e.message || e}`);
      }
    },
  });

  const m = LS.modal({
    title: plan ? 'Изменить план' : 'Новый план подготовки',
    content: body,
    size: 'sm',
    actions,
  });

  // Live-preview derived numbers
  const dateInp = m.body.querySelector('#dh-plan-date');
  const tgtInp  = m.body.querySelector('#dh-plan-target');
  const derived = m.body.querySelector('#dh-plan-derived');
  function updateDerived() {
    const d = dateInp.value;
    if (!/^\d{4}-\d{2}-\d{2}$/.test(d)) { derived.innerHTML = ''; return; }
    const left = daysFromTodayIso(d);
    const tgt  = Math.max(5, Math.min(50, Number(tgtInp.value) || 10));
    derived.innerHTML = `
      <div class="dh-plan-derived-card">
        <span>До экзамена: <b>${left < 0 ? Math.abs(left) + ' дн. назад' : left + ' ' + pluralRu(left, ['день','дня','дней'])}</b></span>
        <span>При ${tgt} задач/день: <b>${left > 0 ? left * tgt : 0} задач максимум</b></span>
      </div>`;
  }
  dateInp.oninput = updateDerived;
  tgtInp.oninput  = updateDerived;
  updateDerived();
}

function addDaysIso(iso, n) {
  const [y, m, d] = iso.split('-').map(Number);
  const dt = new Date(Date.UTC(y, m - 1, d));
  dt.setUTCDate(dt.getUTCDate() + n);
  return toIsoDate(dt);
}
function daysFromTodayIso(iso) {
  const [y, m, d] = iso.split('-').map(Number);
  const t = Date.UTC(y, m - 1, d);
  const n = new Date();
  const today = Date.UTC(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate());
  return Math.round((t - today) / 86400000);
}
function formatRuDate(iso) {
  if (!iso) return '';
  const [y, m, d] = iso.split('-').map(Number);
  const months = ['янв','фев','мар','апр','мая','июн','июл','авг','сен','окт','ноя','дек'];
  return `${d} ${months[m - 1]} ${y}`;
}

function renderWeakTopics(items, examKey) {
  const el = document.getElementById('dh-weak-list');
  if (!el) return;
  if (!items.length) {
    el.innerHTML = `<div class="ep-empty" style="padding:20px">
      <i data-lucide="check-circle-2"></i>
      <p>Слабых тем не выявлено. Решите больше задач, чтобы увидеть приоритеты.</p>
    </div>`;
    return;
  }
  el.innerHTML = `
    <div class="dh-weak-rows">
      ${items.map(w => {
        const tasksLeft = Math.max(0, w.total_tasks - w.solved_tasks);
        return `<a class="dh-weak-row" href="/exam-prep/${examKey}/topics/${encodeURIComponent(w.slug)}">
          <div class="dh-weak-info">
            <div class="dh-weak-title">${escapeHtml(w.title)}</div>
            <div class="dh-weak-meta">${w.correct}/${w.attempts} попыток · ${tasksLeft} задач не взято</div>
          </div>
          <div class="dh-weak-accuracy">${w.accuracy}%</div>
          <div class="dh-weak-cta">Прокачать <i data-lucide="arrow-right"></i></div>
        </a>`;
      }).join('')}
    </div>
    <div class="ep-cta-row" style="margin-top:14px">
      <a class="ep-btn ep-btn-primary" href="/exam-prep/${examKey}/practice?strategy=weak">
        <i data-lucide="target"></i> Тренировать слабые темы
      </a>
    </div>`;
}

function renderMocks(items, examKey) {
  const el = document.getElementById('dh-mocks-list');
  if (!el) return;
  if (!items.length) {
    el.innerHTML = `<div class="ep-empty" style="padding:20px">
      <i data-lucide="timer-off"></i>
      <p>Пробников пока не было. <a href="/exam-prep/${examKey}/mock" style="color:var(--violet)">Запустить первый</a>?</p>
    </div>`;
    return;
  }
  el.innerHTML = items.map(m => {
    const isActive = m.status === 'active';
    const title = m.source === 'variant' ? `Вариант ${m.variant}` : `Случайные ${m.total_tasks}`;
    const when  = relativeTime(m.started_at);
    const score = isActive
      ? `<span class="dh-mock-active">В процессе</span>`
      : `<span class="dh-mock-score">${m.score != null ? m.score + ' баллов' : '—'} · ${m.total_correct}/${m.total_tasks}</span>`;
    return `<a class="dh-mock-row" href="/exam-prep/${examKey}/mock/${m.id}">
      <span class="dh-mock-title">${title}</span>
      ${score}
      <span class="dh-mock-when">${when}</span>
    </a>`;
  }).join('');
}

/* ════════════════════════════════════════════════════════════════
   Utils
   ════════════════════════════════════════════════════════════════ */

function pluralRu(n, forms) {
  const mod10 = n % 10;
  const mod100 = n % 100;
  if (mod100 >= 11 && mod100 <= 14) return forms[2];
  if (mod10 === 1) return forms[0];
  if (mod10 >= 2 && mod10 <= 4) return forms[1];
  return forms[2];
}

function relativeTime(ts) {
  if (!ts) return '';
  const diff = (Date.now() - Number(ts)) / 1000;
  if (diff < 60)       return 'только что';
  if (diff < 3600)     return `${Math.floor(diff/60)} мин назад`;
  if (diff < 86400)    return `${Math.floor(diff/3600)} ч назад`;
  if (diff < 7 * 86400) return `${Math.floor(diff/86400)} ${pluralRu(Math.floor(diff/86400), ['день','дня','дней'])} назад`;
  const d = new Date(Number(ts));
  return `${String(d.getDate()).padStart(2,'0')}.${String(d.getMonth()+1).padStart(2,'0')}`;
}

function toIsoDate(d) {
  const y = d.getUTCFullYear();
  const m = String(d.getUTCMonth() + 1).padStart(2, '0');
  const day = String(d.getUTCDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

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