// Dyktando — ortografia u/ó, rz/ż, h/ch
;(function () {

  // Pairs: key = lowercase match → [choice1, choice2] (shown to user)
  const PAIRS = {
    ch: ['ch', 'h'],
    rz: ['rz', 'ż'],
    ż:  ['rz', 'ż'],
    ó:  ['u',  'ó'],
    u:  ['u',  'ó'],
    h:  ['h',  'ch'],
  }

  // Order matters: digraphs (ch, rz) must be tried before single chars (h)
  const BLANK_RE = /ch|rz|[uóżh]/gi

  let tokens   = []   // {type:'text',content} | {type:'blank',...}
  let blanks   = []   // subset where type==='blank'
  let current  = 0    // index of active blank
  let origText = ''

  // ── DOM refs ─────────────────────────────────────────────────────────────
  const listWrap       = document.getElementById('list-wrap')
  const playWrap       = document.getElementById('play-wrap')
  const textList       = document.getElementById('text-list')
  const customInput    = document.getElementById('custom-input')
  const customStartBtn = document.getElementById('custom-start-btn')
  const playBackBtn    = document.getElementById('play-back-btn')
  const playTitle      = document.getElementById('play-title')
  const textDisplay    = document.getElementById('text-display')
  const choicesEl      = document.getElementById('choices')
  const progressEl     = document.getElementById('blank-progress')
  const summaryWrap    = document.getElementById('summary')
  const summaryText    = document.getElementById('summary-text')
  const summaryScore   = document.getElementById('summary-score')
  const summaryBackBtn = document.getElementById('summary-back-btn')
  const dykScroll      = document.getElementById('dyk-scroll')
  let progressBar = null

  // ── Load texts ────────────────────────────────────────────────────────────
  fetch('json/dyktanda.json')
    .then(r => r.json())
    .then(data => {
      data.forEach(item => {
        const btn = document.createElement('button')
        btn.className = 'list-item-btn'
        btn.textContent = item.name
        btn.addEventListener('click', () => startGame(item.name, item.text))
        textList.appendChild(btn)
      })
    })
    .catch(() => {
      textList.innerHTML = '<p style="color:var(--muted)">Nie udało się wczytać tekstów.</p>'
    })

    // Poczekaj na dynamiczne załadowanie progress bara
    document.addEventListener('DOMContentLoaded', () => {
      // progress bar jest ładowany przez loadComponent w dyktando.html
      const checkProgressBar = () => {
        const el = document.getElementById('dyk-progress-bar-inner')
        if (el) {
          progressBar = el
        } else {
          setTimeout(checkProgressBar, 50)
        }
      }
      checkProgressBar()
    })

  customStartBtn.addEventListener('click', () => {
    const txt = customInput.value.trim()
    if (!txt) return
    startGame('Własny', txt)
  })

  // ── Start game ────────────────────────────────────────────────────────────
  function startGame(title, text) {
    origText = text
    tokens   = []
    blanks   = []
    current  = 0

    // Tokenize: split text into plain segments and blanks
    BLANK_RE.lastIndex = 0
    let lastIdx = 0
    let m
    while ((m = BLANK_RE.exec(text)) !== null) {
      if (m.index > lastIdx) {
        tokens.push({ type: 'text', content: text.slice(lastIdx, m.index) })
      }
      const blank = {
        type:       'blank',
        id:         blanks.length,
        answer:     m[0],                       // original (preserves case)
        choices:    PAIRS[m[0].toLowerCase()],  // pair to show
        start:      m.index,                    // position in origText
        end:        m.index + m[0].length,
        userAnswer: null,
        correct:    null,
      }
      tokens.push(blank)
      blanks.push(blank)
      lastIdx = m.index + m[0].length
    }
    if (lastIdx < text.length) {
      tokens.push({ type: 'text', content: text.slice(lastIdx) })
    }

    // Reset UI
    playTitle.textContent = title
    summaryWrap.classList.add('hidden')
    textDisplay.classList.remove('hidden')
    choicesEl.classList.remove('hidden')
    progressEl.textContent = ''
    if (progressBar) progressBar.style.width = '0%'

    listWrap.classList.add('hidden')
    playWrap.classList.remove('hidden')

    if (blanks.length === 0) {
      renderText()
      showSummary()
    } else {
      renderText()
      activateBlank(0)
    }
  }

  // ── Render the text with blanks ───────────────────────────────────────────
  function renderText() {
    textDisplay.innerHTML = ''
    tokens.forEach(tok => {
      if (tok.type === 'text') {
        textDisplay.appendChild(document.createTextNode(tok.content))
      } else {
        const span = document.createElement('span')
        span.id = `blank-${tok.id}`

        if (tok.correct !== null) {
          // Already answered
          if (tok.correct) {
            span.className = 'dyk-blank dyk-blank--ok'
            span.textContent = tok.answer
          } else {
            span.className = 'dyk-blank dyk-blank--err'
            span.innerHTML = `<s>${esc(tok.userAnswer)}</s><sup class="dyk-correction">${esc(tok.answer)}</sup>`
          }
        } else if (tok.id === current) {
          span.className = 'dyk-blank dyk-blank--active'
          span.textContent = '__'
        } else {
          span.className = 'dyk-blank dyk-blank--pending'
          span.textContent = '__'
        }

        textDisplay.appendChild(span)
      }
    })
  }

  // ── Activate a blank ──────────────────────────────────────────────────────
  function activateBlank(idx) {
    current = idx
    renderText()

    const blank = blanks[idx]

    // Shuffle choices so correct answer isn't always in same position
    const choices = Math.random() < 0.5
      ? [...blank.choices]
      : [...blank.choices].reverse()

    choicesEl.innerHTML = ''
    choices.forEach(choice => {
      const btn = document.createElement('button')
      btn.className = 'choice-btn'
      btn.textContent = choice
      btn.addEventListener('click', () => handleAnswer(blank, choice))
      choicesEl.appendChild(btn)
    })

    progressEl.textContent = `${idx + 1} / ${blanks.length}`

    // Scroll active blank into view
    requestAnimationFrame(() => {
      const el = document.getElementById(`blank-${idx}`)
      if (el) el.scrollIntoView({ block: 'center', behavior: 'smooth' })
    })

    updateProgressBar()
  }

  // ── Handle answer ─────────────────────────────────────────────────────────
  function handleAnswer(blank, choice) {
    blank.correct    = choice.toLowerCase() === blank.answer.toLowerCase()
    blank.userAnswer = choice

    const nextIdx = blank.id + 1
    if (nextIdx >= blanks.length) {
      // Last blank answered: show final state briefly, then summary
      current = blanks.length
      choicesEl.innerHTML = ''
      progressEl.textContent = ''
      renderText()
      setTimeout(showSummary, 500)
    } else {
      activateBlank(nextIdx)
    }
    updateProgressBar()
  }

  // ── Summary ───────────────────────────────────────────────────────────────
  function showSummary() {
    choicesEl.classList.add('hidden')
    textDisplay.classList.add('hidden')
    summaryWrap.classList.remove('hidden')

    const total   = blanks.length
    const correct = blanks.filter(b => b.correct).length

    if (total === 0) {
      summaryScore.textContent = 'Brak liter do uzupełnienia w tym tekście.'
      summaryText.innerHTML = esc(origText)
      updateProgressBar()
    } else {
      summaryScore.textContent = `Poprawnie: ${correct} z ${total}`
      summaryText.innerHTML = buildSummaryHTML()
    }

    dykScroll.scrollTop = 0
  }

  // Build word-coloured summary HTML
  function buildSummaryHTML() {
    // Find word spans (non-whitespace sequences) in original text
    const wordRe = /\S+/g
    const words  = []
    let wm
    while ((wm = wordRe.exec(origText)) !== null) {
      words.push({ start: wm.index, end: wm.index + wm[0].length })
    }

    // Assign each word its blanks and overall status
    words.forEach(w => {
      w.blanks = blanks.filter(b => b.start >= w.start && b.end <= w.end)
      w.status = w.blanks.length === 0 ? 'none'
        : w.blanks.every(b => b.correct) ? 'ok' : 'err'
    })

    let html = ''
    let pos  = 0

    words.forEach(word => {
      // Whitespace / punctuation before this word
      if (word.start > pos) html += esc(origText.slice(pos, word.start))

      // Build inner word HTML (blanks replaced by correct answers, coloured)
      let wPos    = word.start
      let inner   = ''
      word.blanks.forEach(blank => {
        if (blank.start > wPos) inner += esc(origText.slice(wPos, blank.start))
        if (blank.correct) {
          inner += `<span class="dyk-word--ok">${esc(blank.answer)}</span>`
        } else {
          inner += `<span class="dyk-word--err"><s>${esc(blank.userAnswer)}</s><sup class="dyk-correction">${esc(blank.answer)}</sup></span>`
        }
        wPos = blank.end
      })
      inner += esc(origText.slice(wPos, word.end))

      html += word.status !== 'none'
        ? `<span class="dyk-word--${word.status}">${inner}</span>`
        : inner

      pos = word.end
    })

    if (pos < origText.length) html += esc(origText.slice(pos))
    return html
  }

  function updateProgressBar() {
    const total = blanks.length
    if (total === 0) {
      progressBar.style.width = '100%'
      return
    }
    // Use `current` which is the index of the *next* blank to be filled.
    // When the game ends, `current` becomes `blanks.length`.
    const progress = (current / total) * 100
    progressBar.style.width = `${progress}%`
  }

  function esc(s) {
    return (s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
  }

  // ── Navigation ────────────────────────────────────────────────────────────
  // Zakończ button: natychmiast wracamy do listy bez potwierdzenia
  playBackBtn.addEventListener('click', () => {
    goToList()
  })

  summaryBackBtn.addEventListener('click', goToList)

  function goToList() {
    tokens   = []
    blanks   = []
    current  = 0
    textDisplay.innerHTML = ''
    textDisplay.classList.remove('hidden')
    summaryWrap.classList.add('hidden')
    choicesEl.innerHTML = ''
    choicesEl.classList.remove('hidden')
    playWrap.classList.add('hidden')
    listWrap.classList.remove('hidden')
  }

})()
