// Minimal app logic for math training
const state = {
  ops: new Set(),
  mode: null, // 'timed' or 'training'
  score: 0,
  currentProblem: null,
  answerBuffer: '',
  timerId: null,
  timeLeft: 60,
  sessionSolved: 0,
  sessionTarget: 20,
  history: [],
  settings: {
    timedSeconds: 60,
    maxResult: 40,
    maxOperand: 20,
    sessionProblems: 20,
    allowNegative: false,
    allowFraction: false,
  }
}

// elements
const menuScreen = document.getElementById('menu-screen')
const playScreen = document.getElementById('play-screen')
const opsContainer = document.getElementById('ops')
const modeButtons = document.querySelectorAll('.mode-btn')
const opButtons = document.querySelectorAll('.op-btn')
const backBtn = document.getElementById('back-btn')
const problemEl = document.getElementById('problem')
const answerEl = document.getElementById('answer')
const feedbackEl = document.getElementById('feedback')
const timerEl = document.getElementById('timer')
const scoreEl = document.getElementById('score')
const keypad = document.querySelectorAll('.key')
const submitBtn = document.getElementById('submit')
const clearBtn = document.getElementById('clear')
const backspaceBtn = document.getElementById('backspace')
const historyPanel = document.getElementById('history-panel')
const settingTimed = document.getElementById('setting-timed')
const settingMaxResult = document.getElementById('setting-max-result')
const settingMaxOperand = document.getElementById('setting-max-operand')
const settingSessionProblems = document.getElementById('setting-session-problems')
const settingAllowNegative = document.getElementById('setting-allow-negative')
const settingAllowFraction = document.getElementById('setting-allow-fraction')
const saveSettingsBtn = document.getElementById('save-settings')
const resetSettingsBtn = document.getElementById('reset-settings')
const progressInner = document.getElementById('progress_inner')
const dotBtn = document.getElementById('dot')
const negateBtn = document.getElementById('negate')
const summaryOverlay = document.getElementById('summary-overlay')
const summaryText = document.getElementById('summary-text')
const summaryBack = document.getElementById('summary-back')
const statusEl = document.getElementById('status');

// load settings from localStorage
function loadSettings(){
  try{
    const raw = (typeof localStorage !== 'undefined') ? localStorage.getItem('matma:settings') : null
    if (raw) {
      const s = JSON.parse(raw)
      state.settings = Object.assign(state.settings, s)
    }
  }catch(e){ console.warn('settings load failed', e) }
  // reflect to inputs (guard in case some inputs are missing)
  if (settingTimed) settingTimed.value = state.settings.timedSeconds
  if (settingMaxResult) settingMaxResult.value = state.settings.maxResult
  if (settingMaxOperand) settingMaxOperand.value = state.settings.maxOperand
  if (settingSessionProblems) settingSessionProblems.value = state.settings.sessionProblems
  if (settingAllowNegative) settingAllowNegative.checked = !!state.settings.allowNegative
  if (settingAllowFraction) settingAllowFraction.checked = !!state.settings.allowFraction
}

function saveSettings(){
  state.settings.timedSeconds = Math.max(5, Math.min(600, parseInt(settingTimed.value,10) || 60))
  state.settings.maxResult = Math.max(1, Math.min(999, parseInt(settingMaxResult.value,10) || 40))
  state.settings.maxOperand = Math.max(1, Math.min(999, parseInt(settingMaxOperand.value,10) || 20))
  state.settings.sessionProblems = Math.max(1, Math.min(500, parseInt(settingSessionProblems.value,10) || 20))
  state.settings.allowNegative = !!settingAllowNegative.checked
  state.settings.allowFraction = !!settingAllowFraction.checked
  try{ localStorage.setItem('matma:settings', JSON.stringify(state.settings)) }catch(e){console.warn('save failed',e)}

  // visual feedback
  const parent = saveSettingsBtn.parentElement;
  const feedback = document.createElement('span');
  feedback.textContent = 'Zapisano!';
  feedback.style.color = '#16a34a';
  feedback.style.marginLeft = '12px';
  parent.appendChild(feedback);
  setTimeout(()=> parent.removeChild(feedback), 2000);
}

function resetSettings(){
  state.settings = {timedSeconds:60, maxResult:40, maxOperand:20, sessionProblems:20, allowNegative: false, allowFraction: false};
  saveSettings();
  loadSettings();
}

saveSettingsBtn.addEventListener('click', saveSettings)
resetSettingsBtn.addEventListener('click', resetSettings)

loadSettings()

// initial wiring
opButtons.forEach(b => {
  b.addEventListener('click', () => {
    const op = b.dataset.op
    if (state.ops.has(op)) { state.ops.delete(op); b.classList.remove('active') }
    else { state.ops.add(op); b.classList.add('active') }
  })
})

modeButtons.forEach(b => b.addEventListener('click', () => {
  if (state.ops.size === 0) {
    const hint = document.querySelector('.hint-text');
    hint.style.color = '#dc2626';
    hint.style.fontWeight = '600';
    setTimeout(() => {
        hint.style.color = '';
        hint.style.fontWeight = '';
    }, 2000);
    return;
  }
  modeButtons.forEach(x=>x.classList.remove('active'))
  b.classList.add('active')
  state.mode = b.dataset.mode
  startPlay()
}))

backBtn.addEventListener('click', ()=>{
  stopTimer()
  playScreen.classList.add('hidden')
  menuScreen.classList.remove('hidden')
  feedbackEl.textContent = ''
})

function startPlay(){
  menuScreen.classList.add('hidden')
  playScreen.classList.remove('hidden')
  state.score = 0
  state.history = []
  scoreEl.textContent = state.score
  state.answerBuffer = ''
  answerEl.textContent = ''
  feedbackEl.textContent = ''
  state.currentProblem = generateProblem()
  renderProblem()

  if (state.mode === 'timed'){
  if (progressInner) progressInner.style.width = '0%'
  startTimer(state.settings.timedSeconds)
  if (statusEl) statusEl.textContent = 'Na czas';
  if (timerEl) timerEl.classList.remove('hidden');
  } else {
  if (progressInner) progressInner.style.width = '0%'
  state.sessionSolved = 0
  state.sessionTarget = Math.max(1, state.settings.sessionProblems)
  updateProgress()
  if (timerEl) timerEl.classList.add('hidden');
  }
}

function generateProblem(){
  const ops = Array.from(state.ops)
  const maxOp = Math.max(1, state.settings.maxOperand)
  const maxRes = Math.max(1, state.settings.maxResult)
  let a = 0, b = 0, op = '';

  const maxAttempts = 200;
  for (let i = 0; i < maxAttempts; i++) {
    op = ops[Math.floor(Math.random()*ops.length)]
    let candidate = null;

    if (op === 'div'){
      b = randInt(1, maxOp)
      if (!state.settings.allowFraction){
        const maxQByOp = Math.floor(maxOp / b)
        const maxQ = Math.min(maxRes, maxQByOp)
        if (maxQ >= 0) {
            const q = randInt(0, maxQ)
            a = q * b
            if (state.settings.allowNegative && Math.random() < 0.2) a = -a
            candidate = {a,b,op}
        }
      } else {
        const maxResultNByOp = Math.floor((10 * maxOp) / b)
        const maxResultN = Math.min(maxRes * 10, maxResultNByOp)
        if (maxResultN >= 0) {
            const result_n = randInt(0, maxResultN)
            if ((result_n * b) % 10 === 0) {
                a = (result_n * b) / 10
                if (state.settings.allowNegative && Math.random() < 0.2) a = -a
                candidate = {a,b,op}
            }
        }
      }
    } else if (op === 'mul'){
      a = randInt(0, maxOp)
      b = randInt(0, maxOp)
      if (a * b <= maxRes) candidate = {a,b,op}
    } else if (op === 'add'){
      a = randInt(0, maxOp)
      b = randInt(0, maxOp)
      if (a + b <= maxRes) candidate = {a,b,op}
    } else if (op === 'sub'){
      a = randInt(0, maxOp)
      b = randInt(0, maxOp)
      if (!state.settings.allowNegative){
        if (a < b) [a,b] = [b,a]
        if (a - b <= maxRes) candidate = {a,b,op}
      } else {
        if (Math.abs(a - b) <= maxRes) candidate = {a,b,op}
      }
    }

    if (candidate) {
        // Generujemy klucz dla historii. Dla dodawania i mnożenia 2+3 to to samo co 3+2.
        const key = (op === 'add' || op === 'mul')
            ? `${op}:${[candidate.a, candidate.b].sort().join(',')}`
            : `${op}:${candidate.a},${candidate.b}`;

        if (!state.history.includes(key) || i === maxAttempts - 1) {
            state.history.push(key);
            if (state.history.length > 20) state.history.shift();
            return candidate;
        }
    }
  }

  a = Math.min(maxOp, Math.floor(maxRes/2))
  b = Math.min(maxOp, 1)
  return {a,b,op: ops[0] || 'add'}
}

function randInt(min,max){
  return Math.floor(Math.random()*(max-min+1))+min
}

function renderProblem(){
  const p = state.currentProblem
  const map = {add: '+', sub: '−', mul: '×', div: '÷'}
  const symbol = map[p.op] || '?'
  problemEl.textContent = `${p.a} ${symbol} ${p.b}`
}

function submitAnswer(){
  const buf = state.answerBuffer.trim()
  if (buf.length === 0) return
  const given = parseFloat(buf)
  const p = state.currentProblem
  let correct = null
  if (p.op === 'add') correct = p.a + p.b
  else if (p.op === 'sub') correct = p.a - p.b
  else if (p.op === 'mul') correct = p.a * p.b
  else if (p.op === 'div') correct = (p.b === 0) ? null : (p.a / p.b)
  const eps = state.settings.allowFraction ? 1e-6 : 1e-9
  const isCorrect = (correct !== null) && (Math.abs(given - correct) < eps)

  feedbackEl.style.opacity = 1;
  if (isCorrect) {
    state.score += 1
    feedbackEl.textContent = 'Dobrze!'
    feedbackEl.classList.add('correct');
    feedbackEl.classList.remove('incorrect');
  } else {
    const correctAnswer = Number.isFinite(correct) ? parseFloat(correct.toFixed(2)) : '—';
    feedbackEl.textContent = `Poprawna odpowiedź: ${correctAnswer}`
    feedbackEl.classList.add('incorrect');
    feedbackEl.classList.remove('correct');
  }
  scoreEl.textContent = state.score
  state.answerBuffer = ''
  answerEl.textContent = ''

  if (state.mode === 'training'){
    state.sessionSolved++
    updateProgress()
    if (state.sessionSolved >= state.sessionTarget){
      saveSessionToHistory()
      setTimeout(showSummary, 1200);
      return
    }
  }

  setTimeout(() => {
    feedbackEl.style.opacity = 0;
    setTimeout(() => {
        state.currentProblem = generateProblem()
        renderProblem()
    }, 200);
  }, 1200);
}

submitBtn.addEventListener('click', submitAnswer)

keypad.forEach(k => {
  k.addEventListener('click', ()=>{
    const v = k.textContent.trim()
    if (!/^[0-9]$/.test(v)) return
    if (state.answerBuffer.length >= 12) return
    state.answerBuffer += v
    answerEl.textContent = state.answerBuffer
  })
})

if (dotBtn){
  dotBtn.addEventListener('click', ()=>{
    if (!state.settings.allowFraction) return
    if (state.answerBuffer.includes('.')) return
    if (state.answerBuffer.length === 0) state.answerBuffer = '0'
    state.answerBuffer += '.'
    answerEl.textContent = state.answerBuffer
  })
}

if (negateBtn){
  negateBtn.addEventListener('click', ()=>{
    if (!state.settings.allowNegative) return
    if (state.answerBuffer.startsWith('-')) state.answerBuffer = state.answerBuffer.slice(1)
    else state.answerBuffer = '-' + state.answerBuffer
    answerEl.textContent = state.answerBuffer
  })
}

clearBtn.addEventListener('click', ()=>{
  state.answerBuffer = ''
  answerEl.textContent = ''
})

backspaceBtn.addEventListener('click', ()=>{
  state.answerBuffer = state.answerBuffer.slice(0,-1)
  answerEl.textContent = state.answerBuffer
})

function startTimer(seconds){
  state.timeLeft = seconds
  if (timerEl) timerEl.textContent = state.timeLeft

  stopTimer();
  state.timerId = setInterval(()=>{
    state.timeLeft -= 1
    if (timerEl) timerEl.textContent = state.timeLeft
    const pct = Math.max(0, (state.timeLeft / seconds) * 100)
    if (progressInner) progressInner.style.width = pct + '%'
    if (state.timeLeft <= 0) {
      stopTimer()
      endSession()
    }
  },1000)
}

function stopTimer(){
  if (state.timerId) clearInterval(state.timerId)
  state.timerId = null
}

function endSession(){
  saveSessionToHistory()
  showSummary();
}

function showSummary(){
  const total = state.mode === 'timed' ? state.score : state.sessionTarget;
  const correct = state.score;
  const pct = total > 0 ? Math.round((correct / total) * 100) : 0;

  if (state.mode === 'timed') {
      summaryText.textContent = `Koniec czasu! Zdobyłeś ${correct} punktów.`;
  } else {
      summaryText.textContent = `Twój wynik: ${correct} / ${total} poprawnie (${pct}%)`;
  }
  summaryOverlay.classList.remove('hidden');
}

summaryBack.addEventListener('click', ()=>{
  summaryOverlay.classList.add('hidden');
  playScreen.classList.add('hidden');
  menuScreen.classList.remove('hidden');
});

function updateProgress(){
  if (state.mode === 'training'){
  const pct = Math.min(100, Math.round((state.sessionSolved/state.sessionTarget)*100))
  if (progressInner) progressInner.style.width = pct + '%'
  if (statusEl) statusEl.textContent = `${state.sessionSolved}/${state.sessionTarget}`
  }
}

// history persistence
function loadHistory(){
  try{
    const raw = localStorage.getItem('matma:history')
    return raw ? JSON.parse(raw) : []
  }catch(e){ return [] }
}

function saveSessionToHistory(){
  const h = loadHistory()
  const sessionData = {
      ts: Date.now(),
      mode: state.mode,
      score: state.score,
      ops: Array.from(state.ops),
      duration: state.mode === 'timed' ? state.settings.timedSeconds : null,
      problems: state.mode === 'training' ? state.sessionTarget : null
  };
  h.unshift(sessionData);
  while(h.length>50) h.pop()
  try{ localStorage.setItem('matma:history', JSON.stringify(h)) }catch(e){ }
}

function renderHistory(){
  const h = loadHistory()
  historyPanel.innerHTML = ''
  if (h.length === 0) {
    historyPanel.innerHTML = '<p class="history-empty">Brak zapisanych sesji.</p>'
    return
  }
  h.forEach(item => {
    const d = new Date(item.ts).toLocaleString('pl-PL', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
    const modeText = item.mode === 'timed' ? `Na czas (${item.duration}s)` : `Trening (${item.problems} zadań)`;
    const opsText = item.ops.join(', ').replace('add','+').replace('sub','-').replace('mul','×').replace('div','÷');

    const el = document.createElement('div')
    el.className = 'history-item'
    el.innerHTML = `
        <div class="history-item-main">
            <span class="history-score">Wynik: ${item.score}</span>
            <span class="history-ops">${opsText}</span>
        </div>
        <div class="history-item-meta">
            <span>${modeText}</span>
            <span>${d}</span>
        </div>`
    historyPanel.appendChild(el)
  })
}

// Toggle history panel
const historyDetails = historyPanel.closest('details');
if (historyDetails) {
    historyDetails.addEventListener('toggle', () => {
        if (historyDetails.open) {
            renderHistory();
        }
    });
}

// keyboard support
window.addEventListener('keydown', (e)=>{
  if (playScreen.classList.contains('hidden')) return
  if (/^[0-9]$/.test(e.key)){
    if (state.answerBuffer.length < 12) {
      state.answerBuffer += e.key
      answerEl.textContent = state.answerBuffer
    }
  } else if (e.key === 'Backspace'){
    state.answerBuffer = state.answerBuffer.slice(0,-1)
    answerEl.textContent = state.answerBuffer
  } else if (e.key === 'Enter'){
    submitAnswer()
  } else if (e.key === '.' || e.key === ',') {
    dotBtn.click();
  }
})

// Set default active operations
document.addEventListener('DOMContentLoaded', () => {
    opButtons.forEach(btn => {
        const op = btn.dataset.op;
        if (['add', 'sub'].includes(op)) {
            btn.classList.add('active');
            state.ops.add(op);
        }
    });
});
