'use strict';
/* admin → questions section (the biggest — список + Q-modal + CSV) */
(function () {
  'use strict';
  let inited = false;

  let allQuestions = [];
  let editingQId   = null;
  let openQId      = null;
  let _topicMap    = {};
  let _currentType = 'single';
  // window._matchPairs is exposed on window because HTML oninput uses bare `_matchPairs[i].left=this.value`
  window._matchPairs = window._matchPairs || [];
  let _opts        = [];
  let _focusedInput = null;
  let _prevTimer   = null;
  const OPT_LETTERS = 'АБВГДЕ';

  function updateCharCounter(el, cntId, max) {
    const n = el.value.length;
    const cnt = document.getElementById(cntId);
    if (!cnt) return;
    cnt.textContent = `${n} / ${max}`;
    cnt.className = 'char-counter' + (n > max * 0.9 ? ' warn' : '') + (n >= max ? ' over' : '');
  }

  async function onQSubjectChange() {
    const slug = document.getElementById('q-subject').value;
    const sel  = document.getElementById('q-topic');
    sel.innerHTML = '<option value="">Все темы</option>';
    if (slug) {
      try {
        const topics = await LS.getTopics(slug);
        topics.forEach(t => sel.appendChild(new Option(t.name, t.id)));
      } catch {}
    }
    load();
  }

  async function load() {
    const subject  = document.getElementById('q-subject').value;
    const topic_id = document.getElementById('q-topic').value;
    const sort     = document.getElementById('q-sort').value;
    const wrap     = document.getElementById('q-list-wrap');
    wrap.innerHTML = LS.skeleton(5);
    try {
      allQuestions = await LS.getQuestions(subject || null, topic_id || null, sort);
      renderQuestions();
    } catch (e) {
      wrap.innerHTML = `<div class="error">Ошибка загрузки: ${esc(e.message)}</div>`;
    }
  }

  function renderQuestions() {
    const { DIFFS } = AdminCtx;
    const search   = document.getElementById('q-search').value.toLowerCase();
    const filtered = search
      ? allQuestions.filter(q => q.text.toLowerCase().includes(search) || (q.topic||'').toLowerCase().includes(search))
      : allQuestions;

    document.getElementById('q-count').textContent = `${filtered.length} вопросов`;

    if (!filtered.length) {
      document.getElementById('q-list-wrap').innerHTML = '<div class="empty">Вопросов не найдено</div>';
      return;
    }

    const wrap = document.getElementById('q-list-wrap');
    wrap.innerHTML =
      `<div class="q-list">${filtered.map(q => {
        const diffCls = `diff-${q.difficulty}`;
        const optsHtml = (q.options || []).map(o =>
          `<div class="q-opt-row ${o.is_correct ? 'correct' : ''}">
             <span class="q-opt-icon">${o.is_correct ? '<i data-lucide="check" style="width:13px;height:13px"></i>' : '<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/></svg>'}</span>${esc(o.text)}
           </div>`).join('');
        const explHtml = q.explanation
          ? `<div class="q-expl"><strong>Пояснение:</strong> ${esc(q.explanation)}</div>` : '';
        return `<div class="q-card" id="qcard-${q.id}">
          <div class="q-card-head">
            <span class="q-card-num">#${q.id}</span>
            <div class="q-card-body" onclick="toggleQDetail(${q.id})">
              <div class="q-card-text">${esc(q.text)}</div>
              <div class="q-card-meta">
                ${q.subject_name ? `<span class="q-badge q-badge-subj">${esc(q.subject_name)}</span>` : ''}
                ${q.topic ? `<span class="q-badge q-badge-topic">${esc(q.topic)}</span>` : ''}
                <span class="q-badge ${diffCls}">${DIFFS[q.difficulty]||q.difficulty}</span>
                <span style="font-size:0.72rem;color:var(--text-3);background:rgba(15,23,42,0.05);padding:2px 7px;border-radius:999px">${{single:'Один',multi:'Несколько',true_false:'Верно/Неверно',short_answer:'Краткий',matching:'Сопост.'}[q.type]||q.type||'Один'}</span>
                <span style="font-size:0.75rem;color:var(--text-3)">${q.options?.length||0} вар.</span>
              </div>
            </div>
            <div class="q-card-actions">
              <button class="btn-edit-q" onclick="editQ(${q.id})">Изменить</button>
              <button class="btn-dup-q"  onclick="dupQ(${q.id})" title="Дублировать">⧉</button>
              <button class="btn-del-q"  onclick="deleteQ(${q.id})" title="Удалить"><i data-lucide="x" style="width:14px;height:14px"></i></button>
            </div>
          </div>
          <div class="q-card-detail" id="qdetail-${q.id}">
            ${optsHtml}${explHtml}
          </div>
        </div>`;
      }).join('')}</div>`;
    AdminCtx.renderMath(wrap);
    if (window.lucide) lucide.createIcons();
  }

  function toggleQDetail(id) {
    if (openQId === id) {
      document.getElementById('qdetail-' + id)?.classList.remove('open');
      openQId = null; return;
    }
    if (openQId) document.getElementById('qdetail-' + openQId)?.classList.remove('open');
    document.getElementById('qdetail-' + id)?.classList.add('open');
    openQId = id;
  }

  async function dupQ(id) {
    try {
      const { id: newId } = await LS.duplicateQuestion(id);
      await load();
      setTimeout(() => document.getElementById('qcard-' + newId)?.scrollIntoView({ behavior:'smooth', block:'center' }), 300);
    } catch (e) { LS.toast('Ошибка: ' + e.message, 'error'); }
  }

  async function deleteQ(id) {
    if (!await LS.confirm(`Удалить вопрос #${id}?`, { title: 'Удалить вопрос', confirmText: 'Удалить' })) return;
    try {
      await LS.deleteQuestion(id);
      allQuestions = allQuestions.filter(q => q.id !== id);
      renderQuestions();
    } catch (e) { LS.toast('Ошибка: ' + e.message, 'error'); }
  }

  /* ─── Question type ─── */
  function setQType(type) {
    _currentType = type;
    document.querySelectorAll('[data-type]').forEach(b => b.classList.toggle('active', b.dataset.type === type));
    const isMatching   = type === 'matching';
    const isShort      = type === 'short_answer';
    const showOpts     = !isShort && !isMatching;
    const optsHeader = document.getElementById('qf-opts-header');
    if (optsHeader) optsHeader.style.display = showOpts ? '' : 'none';
    document.getElementById('qf-opts').style.display       = showOpts ? '' : 'none';
    document.getElementById('qf-short-wrap').style.display = isShort    ? '' : 'none';
    document.getElementById('qf-match-wrap').style.display = isMatching ? '' : 'none';
    document.getElementById('btn-add-opt').style.display   = showOpts && type !== 'true_false' ? '' : 'none';

    if (type === 'true_false') {
      initOpts([{ text:'Верно', is_correct:false }, { text:'Неверно', is_correct:false }]);
    } else if (isShort) {
      _opts = [];
    } else if (isMatching) {
      _opts = [];
      if (window._matchPairs.length === 0) window._matchPairs = [{left:'',right:''},{left:'',right:''},{left:'',right:''}];
      renderMatchRows();
    } else {
      if (_opts.length === 0 || _opts[0]?.text === 'Верно') initOpts([{},{},{},{}]);
      else renderOptRows(_opts);
    }
  }

  function renderMatchRows() {
    const cont = document.getElementById('qf-match-rows');
    cont.innerHTML = window._matchPairs.map((p, i) => `
      <div style="display:grid;grid-template-columns:1fr 1fr auto;gap:8px;margin-bottom:8px" data-mi="${i}">
        <input type="text" class="form-ctrl" placeholder="Элемент…" value="${esc(p.left)}"
          oninput="window._matchPairs[${i}].left=this.value" style="margin:0" />
        <input type="text" class="form-ctrl" placeholder="Пара к нему…" value="${esc(p.right)}"
          oninput="window._matchPairs[${i}].right=this.value" style="margin:0" />
        <button type="button" onclick="removeMatchPair(${i})" style="border:none;background:none;color:var(--text-3);cursor:pointer;padding:0 6px;display:flex;align-items:center" title="Удалить"><i data-lucide="x" style="width:15px;height:15px"></i></button>
      </div>`).join('');
    if (window.lucide) lucide.createIcons();
  }

  function addMatchPair() {
    window._matchPairs.push({left:'',right:''});
    renderMatchRows();
  }

  function removeMatchPair(i) {
    window._matchPairs.splice(i, 1);
    renderMatchRows();
  }

  /* ─── Formula bar ─── */
  document.addEventListener('focusin', e => {
    if (e.target.closest && e.target.closest('#q-modal') &&
        (e.target.tagName === 'TEXTAREA' || (e.target.tagName === 'INPUT' && e.target.type === 'text'))) {
      _focusedInput = e.target;
    }
  });

  function ins(latex) {
    const el = _focusedInput || document.getElementById('qf-text');
    if (!el) return;
    const s = el.selectionStart ?? el.value.length;
    const e2= el.selectionEnd   ?? el.value.length;
    const before = el.value.slice(0, s), after = el.value.slice(e2);
    const opens  = (before.match(/\\\(/g)||[]).length;
    const closes = (before.match(/\\\)/g)||[]).length;
    const insert = opens > closes ? latex : `\\(${latex}\\)`;
    el.value = before + insert + after;
    el.setSelectionRange(s + insert.length, s + insert.length);
    el.focus();
    updateQPreview();
  }

  function wrapMath() {
    const el = _focusedInput || document.getElementById('qf-text');
    if (!el) return;
    const s = el.selectionStart, e2 = el.selectionEnd;
    const sel = el.value.slice(s, e2) || 'x';
    el.value = el.value.slice(0, s) + `\\(${sel}\\)` + el.value.slice(e2);
    el.focus();
    updateQPreview();
  }

  /* ─── Live preview ─── */
  function updateQPreview() {
    clearTimeout(_prevTimer);
    _prevTimer = setTimeout(() => {
      const text = (document.getElementById('qf-text').value || '').trim();
      const el   = document.getElementById('q-preview-text');
      const wrap = document.getElementById('q-preview-wrap');
      wrap.classList.toggle('hidden', !text);
      if (!text) return;
      el.textContent = text;
      AdminCtx.renderMath(el);
    }, 150);
  }

  // Formula bar toggle (default collapsed)
  window.toggleFormulaBar = function () {
    const bar = document.getElementById('formula-bar');
    const btn = document.getElementById('qf-fml-toggle');
    const open = bar.classList.toggle('visible');
    btn.classList.toggle('open', open);
  };

  // Wire textarea input to preview
  setTimeout(() => {
    const ta = document.getElementById('qf-text');
    if (ta) ta.addEventListener('input', updateQPreview);
  }, 0);

  /* ─── Dynamic options ─── */
  function renderOptRows(opts) {
    const grid    = document.getElementById('qf-opts');
    const isMulti = _currentType === 'multi';
    grid.innerHTML = opts.map((o, i) => `
      <div class="opt-row${o.is_correct ? ' opt-correct' : ''}" data-i="${i}">
        <span class="opt-letter">${OPT_LETTERS[i]}</span>
        ${isMulti
          ? `<input type="checkbox" class="opt-radio" value="${i}" ${o.is_correct ? 'checked' : ''}
                 onchange="onCheckChange(${i}, this.checked)" />`
          : `<input type="radio" name="qf-correct" class="opt-radio" value="${i}" ${o.is_correct ? 'checked' : ''}
                 onchange="onRadioChange(${i})" />`}
        <input type="text" class="opt-input" placeholder="Вариант ${OPT_LETTERS[i]}"
               value="${esc(o.text||'')}" oninput="syncOptText(${i}, this.value)" />
        ${opts.length > 2
          ? `<button type="button" class="btn-rem-opt" onclick="removeOpt(${i})" title="Удалить">−</button>`
          : '<span style="width:24px;flex-shrink:0"></span>'}
      </div>`).join('');
    document.getElementById('btn-add-opt').style.display = opts.length >= 6 ? 'none' : '';
  }

  function onCheckChange(idx, checked) {
    _opts[idx].is_correct = checked;
    document.querySelector(`#qf-opts .opt-row[data-i="${idx}"]`)?.classList.toggle('opt-correct', checked);
  }

  function initOpts(opts) {
    _opts = opts.length ? opts.map(o => ({ text: o.text||'', is_correct: !!o.is_correct }))
                        : [{text:'',is_correct:false},{text:'',is_correct:false},{text:'',is_correct:false},{text:'',is_correct:false}];
    renderOptRows(_opts);
  }

  function onRadioChange(idx) {
    _opts.forEach((o, i) => o.is_correct = (i === idx));
    renderOptRows(_opts);
  }

  function syncOptText(idx, val) { _opts[idx].text = val; }

  function addOpt() {
    if (_opts.length >= 6) return;
    _opts.push({ text: '', is_correct: false });
    renderOptRows(_opts);
    const rows = document.querySelectorAll('#qf-opts .opt-row');
    rows[rows.length - 1]?.querySelector('input[type=text]')?.focus();
  }

  function removeOpt(idx) {
    if (_opts.length <= 2) return;
    const wasCorrect = _opts[idx].is_correct;
    _opts.splice(idx, 1);
    if (wasCorrect && _opts.length > 0) _opts[0].is_correct = true;
    renderOptRows(_opts);
  }

  /* ─── Modal ─── */
  function openQModal(q = null) {
    editingQId = q ? q.id : null;
    document.getElementById('q-modal-title').textContent = q ? `Редактировать вопрос #${q.id}` : 'Добавить вопрос';
    const textEl = document.getElementById('qf-text');
    textEl.value = q?.text || '';
    updateCharCounter(textEl, 'qf-text-cnt', 500);
    document.getElementById('qf-explanation').value   = q?.explanation || '';
    document.getElementById('qf-difficulty').value    = q?.difficulty ?? 2;
    document.getElementById('qf-subject').value       = q?.subject_slug || '';
    document.getElementById('qf-topic-text').value    = q?.topic || '';
    document.getElementById('qf-correct-text').value  = q?.correct_text || '';
    document.getElementById('qf-error').textContent   = '';
    const imgVal = q?.image || '';
    document.getElementById('qf-image').value = imgVal;
    updateImagePreview(imgVal);

    if (q?.type === 'matching') {
      window._matchPairs = (q.options || []).map(o => ({ left: o.text, right: o.match_pair || '' }));
      if (!window._matchPairs.length) window._matchPairs = [{left:'',right:''},{left:'',right:''},{left:'',right:''}];
    } else {
      window._matchPairs = [];
    }
    setQType(q?.type || 'single');
    if (q?.type !== 'matching') initOpts(q?.options || []);
    updateQPreview();
    loadQModalTopics();
    document.getElementById('q-modal').classList.add('open');
    setTimeout(() => textEl.focus(), 80);
  }

  function editQ(id) {
    const q = allQuestions.find(x => x.id === id);
    if (q) openQModal(q);
  }

  function closeQModal() {
    document.getElementById('q-modal').classList.remove('open');
    editingQId = null;
  }

  async function loadQModalTopics() {
    const slug = document.getElementById('qf-subject').value;
    const dl   = document.getElementById('qf-topic-list');
    dl.innerHTML = '';
    _topicMap = {};
    if (!slug) return;
    try {
      const topics = await LS.getTopics(slug);
      topics.forEach(t => {
        dl.appendChild(new Option(t.name));
        _topicMap[t.name.toLowerCase()] = t.id;
      });
    } catch {}
  }

  async function saveQuestion() {
    const text         = document.getElementById('qf-text').value.trim();
    const explanation  = document.getElementById('qf-explanation').value.trim();
    const difficulty   = Number(document.getElementById('qf-difficulty').value);
    const subject_slug = document.getElementById('qf-subject').value;
    const topicText    = document.getElementById('qf-topic-text').value.trim();
    const type         = _currentType;
    const errEl        = document.getElementById('qf-error');
    errEl.textContent  = '';

    if (!subject_slug) { errEl.textContent = 'Выберите предмет'; return; }
    if (!text)         { errEl.textContent = 'Введите текст вопроса'; return; }

    let options      = null;
    let correct_text = null;

    if (type === 'short_answer') {
      correct_text = document.getElementById('qf-correct-text').value.trim();
      if (!correct_text) { errEl.textContent = 'Введите правильный ответ'; return; }
    } else if (type === 'matching') {
      document.querySelectorAll('#qf-match-rows [data-mi]').forEach((row, i) => {
        const [l, r] = row.querySelectorAll('input');
        if (window._matchPairs[i]) { window._matchPairs[i].left = l.value.trim(); window._matchPairs[i].right = r.value.trim(); }
      });
      if (window._matchPairs.length < 2) { errEl.textContent = 'Нужно минимум 2 пары'; return; }
      if (window._matchPairs.some(p => !p.left || !p.right)) { errEl.textContent = 'Заполните все пары'; return; }
      options = window._matchPairs.map(p => ({ text: p.left, match_pair: p.right, is_correct: 0 }));
    } else {
      document.querySelectorAll('#qf-opts .opt-row').forEach((row, i) => {
        if (_opts[i]) _opts[i].text = row.querySelector('input[type=text]').value.trim();
      });
      options = _opts.map(o => ({ text: o.text, is_correct: o.is_correct }));
      if (options.length < 2)           { errEl.textContent = 'Нужно минимум 2 варианта ответа'; return; }
      if (options.some(o => !o.text))   { errEl.textContent = 'Заполните все варианты ответов'; return; }
      if (!options.some(o => o.is_correct)) { errEl.textContent = 'Отметьте правильный ответ'; return; }
    }

    const knownId    = _topicMap[topicText.toLowerCase()];
    const topic_id   = knownId || null;
    const topic_name = !knownId && topicText ? topicText : null;

    const image = document.getElementById('qf-image').value.trim() || null;

    const btn = document.getElementById('qf-save');
    btn.disabled = true; btn.textContent = 'Сохранение…';
    try {
      if (editingQId) {
        await LS.updateQuestion(editingQId, { text, type, correct_text, difficulty, explanation: explanation||null, topic_id, topic_name, options, image });
      } else {
        await LS.createQuestion({ subject_slug, topic_id, topic_name, text, type, correct_text, difficulty, explanation: explanation||null, options, image });
      }
      closeQModal();
      load();
    } catch (e) {
      errEl.textContent = 'Ошибка: ' + e.message;
    } finally {
      btn.disabled = false; btn.textContent = 'Сохранить';
    }
  }

  /* ── Image upload & preview ── */
  function updateImagePreview(url) {
    const wrap = document.getElementById('qf-image-preview');
    const img  = document.getElementById('qf-image-img');
    if (url) { img.src = url; wrap.classList.add('visible'); }
    else     { wrap.classList.remove('visible'); img.src = ''; }
  }

  function clearQuestionImage() {
    document.getElementById('qf-image').value = '';
    updateImagePreview('');
  }

  async function handleImageFileSelect(input) {
    const file = input.files[0];
    if (!file) return;
    input.value = '';
    const btn = document.getElementById('btn-img-upload');
    const lbl = document.getElementById('btn-img-upload-lbl');
    btn.disabled = true;
    lbl.textContent = 'Загрузка…';
    try {
      const fd = new FormData();
      fd.append('file', file);
      fd.append('title', 'Question image: ' + file.name);
      fd.append('is_public', '1');
      const res = await fetch('/api/files', {
        method: 'POST',
        headers: { Authorization: 'Bearer ' + localStorage.getItem('ls_token') },
        body: fd
      });
      if (!res.ok) throw new Error((await res.json()).error || res.statusText);
      const { id } = await res.json();
      const url = `/api/files/${id}/download`;
      document.getElementById('qf-image').value = url;
      updateImagePreview(url);
    } catch (e) {
      document.getElementById('qf-error').textContent = 'Ошибка загрузки: ' + e.message;
    } finally {
      btn.disabled = false;
      lbl.textContent = 'Загрузить';
    }
  }

  document.addEventListener('DOMContentLoaded', () => {
    const imgInput = document.getElementById('qf-image');
    if (imgInput) imgInput.addEventListener('input', e => updateImagePreview(e.target.value.trim()));
  });

  /* ── CSV Import ── */
  async function importCSVFile(input) {
    const file = input.files[0];
    if (!file) return;
    input.value = '';
    const fd = new FormData();
    fd.append('file', file);
    const btn = document.querySelector('[onclick="document.getElementById(\'csv-file-input\').click()"]');
    if (btn) { btn.disabled = true; btn.textContent = 'Импорт…'; }
    try {
      const { imported, errors } = await LS.importQuestions(fd);
      LS.toast(`Импортировано: ${imported} вопросов${errors.length ? ` (${errors.length} ошибок)` : ''}`, imported > 0 ? 'success' : 'warn', 5000);
      load();
    } catch (e) {
      LS.toast('Ошибка импорта: ' + e.message, 'error');
    } finally {
      if (btn) { btn.disabled = false; btn.innerHTML = '<i data-lucide="upload" style="width:14px;height:14px;vertical-align:-2px"></i> Импорт CSV'; if(window.lucide)lucide.createIcons(); }
    }
  }

  function downloadCSVTemplate(e) {
    e.preventDefault();
    const header = 'subject_slug;topic;text;difficulty;type;opt1;c1;opt2;c2;opt3;c3;opt4;c4;correct_text;explanation;year';
    const example = [
      'bio;Клетки;Что является «электростанцией» клетки?;2;single;Митохондрия;1;Рибосома;0;Лизосома;0;Ядро;0;;Митохондрии синтезируют АТФ;2024',
      'bio;Клетки;Какие органоиды участвуют в синтезе белка?;2;multi;Рибосома;1;Митохондрия;0;Эндоплазматическая сеть;1;Лизосома;0;;',
      'chem;Кислоты;Формула серной кислоты;1;short_answer;;;;;;;;H2SO4;;',
    ].join('\n');
    const blob = new Blob(['﻿' + header + '\n' + example], { type: 'text/csv;charset=utf-8' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'questions_template.csv';
    a.click();
  }

  // Expose handlers used by onclick (HTML or sibling sections)
  window.onQSubjectChange = onQSubjectChange;
  window.loadQuestions = load;
  window.renderQuestions = renderQuestions;
  window.toggleQDetail = toggleQDetail;
  window.dupQ = dupQ;
  window.deleteQ = deleteQ;
  window.setQType = setQType;
  window.addMatchPair = addMatchPair;
  window.removeMatchPair = removeMatchPair;
  window.ins = ins;
  window.wrapMath = wrapMath;
  window.updateQPreview = updateQPreview;
  window.onCheckChange = onCheckChange;
  window.onRadioChange = onRadioChange;
  window.syncOptText = syncOptText;
  window.addOpt = addOpt;
  window.removeOpt = removeOpt;
  window.openQModal = openQModal;
  window.editQ = editQ;
  window.closeQModal = closeQModal;
  window.loadQModalTopics = loadQModalTopics;
  window.saveQuestion = saveQuestion;
  window.updateImagePreview = updateImagePreview;
  window.clearQuestionImage = clearQuestionImage;
  window.handleImageFileSelect = handleImageFileSelect;
  window.importCSVFile = importCSVFile;
  window.downloadCSVTemplate = downloadCSVTemplate;
  window.updateCharCounter = updateCharCounter;
  window.AdminSections = window.AdminSections || {};
  window.AdminSections.questions = {
    init: async () => { if (inited) return; inited = true; await load(); },
    reload: load,
    openModal: openQModal,
    loadModalTopics: loadQModalTopics,
  };
})();
