const API = 'api/game_questions_admin.php';

const GAME_TYPES = {
  memory: 'Memory Dates',
  timeline: 'Timeline Battle',
  popcorn: 'Popcorn Clash',
  geo: 'Géo-devinette',
  sondage: 'Sondage',
  juste_prix: 'Le Juste Prix',
  alcool_order: 'Degré Battle'
};

const TYPE_HELP = {
  memory: 'Memory : question = événement, réponse/date = date à associer. date_event peut contenir une date plus précise.',
  timeline: 'Timeline : question = événement, réponse = année de tri, date_event = date affichée après validation.',
  popcorn: 'Popcorn : mets 4 options et 3 indices progressifs. Réponse exacte = bonne option.',
  geo: 'Géo-devinette : réponse exacte = lieu à deviner, indices = indices progressifs.',
  sondage: 'Sondage : réponse exacte = pourcentage numérique, par exemple 39. Les options ne sont pas utiles.',
  juste_prix: 'Juste Prix : réponse exacte = valeur numérique. La question doit préciser l’unité.',
  alcool_order: "Degré Battle : question = boisson, réponse = degré numérique. date_event peut afficher le degré avec % vol. Classement du plus faible au plus fort."
};

let page = 1;
let total = 0;
let lastQuestions = [];

const $ = (id) => document.getElementById(id);

function setStatus(message, isError = false) {
  const el = $('adminStatus');
  if (!el) return;
  el.textContent = message || '';
  el.style.color = isError ? 'var(--bad)' : 'var(--muted)';
}

function getKey() {
  return $('adminKey').value.trim();
}

async function request(action, options = {}) {
  const key = encodeURIComponent(getKey());
  const res = await fetch(`${API}?action=${action}&key=${key}${options.query || ''}`, {
    method: options.method || 'GET',
    headers: { 'Content-Type': 'application/json' },
    body: options.body ? JSON.stringify(options.body) : undefined
  });
  const data = await res.json().catch(() => ({ message: 'Réponse serveur invalide' }));
  if (!res.ok) throw new Error(data.message || 'Erreur serveur');
  return data;
}

function fillGameTypeSelects() {
  const options = Object.entries(GAME_TYPES)
    .map(([key, label]) => `<option value="${key}">${label}</option>`)
    .join('');
  $('gameTypeInput').innerHTML = options;
  $('filterGameType').innerHTML = `<option value="">Tous les jeux</option>${options}`;
  updateHelp();
}

function updateHelp() {
  const type = $('gameTypeInput').value;
  $('typeHelp').textContent = TYPE_HELP[type] || '';
}

function lines(id) {
  return $(id).value.split(/\n+/).map(v => v.trim()).filter(Boolean);
}

function formData() {
  return {
    id: Number($('questionId').value || 0),
    game_type: $('gameTypeInput').value,
    question: $('questionInput').value.trim(),
    options: lines('optionsInput'),
    answer: $('answerInput').value.trim(),
    explanation: $('explanationInput').value.trim(),
    date_event: $('dateEventInput').value.trim(),
    hints: lines('hintsInput'),
    active: $('activeInput').checked ? 1 : 0
  };
}

function resetForm() {
  $('gameQuestionForm').reset();
  $('questionId').value = '';
  $('activeInput').checked = true;
  $('formTitle').textContent = 'Nouvelle question de jeu';
  updateHelp();
}

function editQuestion(id) {
  const q = lastQuestions.find(item => item.id === id);
  if (!q) return;
  $('questionId').value = q.id;
  $('gameTypeInput').value = q.game_type;
  $('questionInput').value = q.question;
  $('optionsInput').value = (q.options || []).join('\n');
  $('answerInput').value = q.answer;
  $('dateEventInput').value = q.date_event || '';
  $('hintsInput').value = (q.hints || []).join('\n');
  $('explanationInput').value = q.explanation || '';
  $('activeInput').checked = Number(q.active) === 1;
  $('formTitle').textContent = `Modifier #${q.id}`;
  updateHelp();
  window.scrollTo({ top: 0, behavior: 'smooth' });
}

async function saveQuestion(e) {
  e.preventDefault();
  try {
    const payload = formData();
    if (!payload.question || !payload.answer) {
      setStatus('Question et réponse exacte sont obligatoires.', true);
      return;
    }
    const data = await request('save', { method: 'POST', body: payload });
    setStatus(data.message);
    resetForm();
    loadQuestions();
  } catch (err) {
    setStatus(err.message, true);
  }
}

async function toggleQuestion(id, active) {
  try {
    const data = await request('toggle', { method: 'POST', body: { id, active: active ? 1 : 0 } });
    setStatus(data.message);
    loadQuestions();
  } catch (err) {
    setStatus(err.message, true);
  }
}

async function deleteQuestion(id) {
  if (!confirm('Supprimer définitivement cette question de jeu ?')) return;
  try {
    const data = await request('delete', { method: 'POST', body: { id } });
    setStatus(data.message);
    loadQuestions();
  } catch (err) {
    setStatus(err.message, true);
  }
}

function escapeHtml(value) {
  return String(value ?? '')
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#039;');
}

function renderQuestions(questions) {
  const list = $('questionList');
  if (!questions.length) {
    list.innerHTML = '<p class="muted">Aucune question de jeu trouvée.</p>';
    return;
  }
  list.innerHTML = questions.map(q => {
    const label = GAME_TYPES[q.game_type] || q.game_type;
    const active = Number(q.active) === 1;
    const options = (q.options || []).length ? `${q.options.length} options` : 'sans options';
    const hints = (q.hints || []).length ? `${q.hints.length} indices` : 'sans indices';
    return `
      <article class="question-row ${active ? '' : 'is-off'}">
        <div>
          <h3>${escapeHtml(q.question)}</h3>
          <div class="question-meta">
            <span>#${q.id}</span>
            <span>${escapeHtml(label)}</span>
            <span>${options}</span>
            <span>${hints}</span>
            <span>${active ? 'active' : 'désactivée'}</span>
          </div>
          <p class="question-answer">Réponse : ${escapeHtml(q.answer)}${q.date_event ? ` · Date : ${escapeHtml(q.date_event)}` : ''}</p>
          ${q.explanation ? `<p class="muted">${escapeHtml(q.explanation)}</p>` : ''}
        </div>
        <div class="question-actions">
          <button class="btn ghost" type="button" onclick="editQuestion(${q.id})">Modifier</button>
          <button class="btn ghost" type="button" onclick="toggleQuestion(${q.id}, ${active ? 0 : 1})">${active ? 'Désactiver' : 'Activer'}</button>
          <button class="btn ghost" type="button" onclick="deleteQuestion(${q.id})">Supprimer</button>
        </div>
      </article>`;
  }).join('');
}

async function loadQuestions() {
  try {
    const params = new URLSearchParams();
    const type = $('filterGameType').value;
    const active = $('filterActive').value;
    const q = $('searchInput').value.trim();
    if (type) params.set('game_type', type);
    if (active !== '') params.set('active', active);
    if (q) params.set('q', q);
    params.set('page', page);
    params.set('limit', 30);
    const data = await request('list', { query: `&${params.toString()}` });
    lastQuestions = data.questions || [];
    total = data.total || 0;
    renderQuestions(lastQuestions);
    const maxPage = Math.max(1, Math.ceil(total / 30));
    $('pageInfo').textContent = `Page ${page}/${maxPage} - ${total} question(s)`;
    $('prevPageBtn').disabled = page <= 1;
    $('nextPageBtn').disabled = page >= maxPage;
  } catch (err) {
    setStatus(err.message, true);
  }
}

function parseCsvLine(line, delimiter = ';') {
  const cells = [];
  let current = '';
  let quoted = false;
  for (let i = 0; i < line.length; i++) {
    const ch = line[i];
    if (ch === '"') {
      if (quoted && line[i + 1] === '"') {
        current += '"';
        i++;
      } else {
        quoted = !quoted;
      }
    } else if (ch === delimiter && !quoted) {
      cells.push(current);
      current = '';
    } else {
      current += ch;
    }
  }
  cells.push(current);
  return cells.map(v => v.trim());
}

function splitPipe(value) {
  return String(value || '').split('|').map(v => v.trim()).filter(Boolean);
}

function parseCsv(text) {
  const lines = text.replace(/\r/g, '').split('\n').filter(line => line.trim());
  if (lines.length < 2) return [];
  const delimiter = lines[0].includes(';') ? ';' : ',';
  const headers = parseCsvLine(lines[0], delimiter).map(h => h.toLowerCase().trim());
  return lines.slice(1).map(line => {
    const cells = parseCsvLine(line, delimiter);
    const row = {};
    headers.forEach((h, i) => row[h] = cells[i] || '');
    return {
      game_type: row.game_type,
      question: row.question,
      options: splitPipe(row.options),
      answer: row.answer,
      explanation: row.explanation || '',
      date_event: row.date_event || '',
      hints: splitPipe(row.hints),
      active: row.active === '0' ? 0 : 1
    };
  }).filter(q => q.game_type && q.question && q.answer);
}

async function importCsv() {
  try {
    const questions = parseCsv($('csvInput').value);
    if (!questions.length) {
      setStatus('CSV vide ou colonnes manquantes.', true);
      return;
    }
    const data = await request('bulk', { method: 'POST', body: { questions } });
    setStatus(`${data.message} : ${data.imported} importée(s), ${data.skipped} ignorée(s).`);
    $('csvInput').value = '';
    page = 1;
    loadQuestions();
  } catch (err) {
    setStatus(err.message, true);
  }
}

function loadTemplate() {
  $('csvInput').value = [
    'game_type;question;options;answer;explanation;date_event;hints;active',
    'timeline;Lancement de YouTube;;2005;YouTube est lancé en 2005 par Steve Chen, Chad Hurley et Jawed Karim.;2005;;1',
    'popcorn;De quelle œuvre parle-t-on ?;Stranger Things|Dark|Wednesday|The Boys;Stranger Things;Série Netflix avec Eleven, Hawkins et le monde à l’envers.;;Une ville américaine étrange|Un monde parallèle|Eleven adore les gaufres;1',
    'geo;Quel lieu faut-il deviner ?;;Paris;Capitale française très visitée.;;Ville européenne|On y trouve la tour Eiffel|Capitale de la France;1',
    'sondage;Quel pourcentage de Français disent regarder YouTube chaque semaine ?;;72;Exemple de question à ajuster avec une vraie source.;;;1',
    'juste_prix;Combien coûte environ une PS5 neuve en euros ?;;550;Valeur indicative à mettre à jour selon le marché.;;;1'
  ].join('\n');
}

function init() {
  fillGameTypeSelects();
  $('adminKey').value = localStorage.getItem('tq_admin_key') || '';
  $('saveKeyBtn').addEventListener('click', () => {
    localStorage.setItem('tq_admin_key', getKey());
    setStatus('Clé enregistrée sur cet appareil.');
    loadQuestions();
  });
  $('gameTypeInput').addEventListener('change', updateHelp);
  $('gameQuestionForm').addEventListener('submit', saveQuestion);
  $('resetFormBtn').addEventListener('click', resetForm);
  $('refreshBtn').addEventListener('click', () => { page = 1; loadQuestions(); });
  $('importCsvBtn').addEventListener('click', importCsv);
  $('loadTemplateBtn').addEventListener('click', loadTemplate);
  $('prevPageBtn').addEventListener('click', () => { if (page > 1) { page--; loadQuestions(); } });
  $('nextPageBtn').addEventListener('click', () => { page++; loadQuestions(); });
  ['filterGameType', 'filterActive'].forEach(id => $(id).addEventListener('change', () => { page = 1; loadQuestions(); }));
  $('searchInput').addEventListener('input', () => {
    clearTimeout(window.__adminGameSearchTimer);
    window.__adminGameSearchTimer = setTimeout(() => { page = 1; loadQuestions(); }, 250);
  });
  if (getKey()) loadQuestions();
}

window.editQuestion = editQuestion;
window.toggleQuestion = toggleQuestion;
window.deleteQuestion = deleteQuestion;
document.addEventListener('DOMContentLoaded', init);
