(() => {

    let ALPHABET = [];
    let data = [];
    let editing = new Set();
    let pendingDelete = null;

    // QR Code generation function using backend
    async function generateQRCode(secret, imgElement) {
      try {
        const response = await fetch(`/admin/generate_qr/${encodeURIComponent(secret)}`);
        const data = await response.json();
        imgElement.src = `data:image/png;base64,${data.qr_code}`;
      } catch (error) {
        console.error('Error generating QR code:', error);
      }
    }

    // helper to format DD.MM.YYYY → YYYY-MM-DD
    function formatISO(d) {
      const [dd, mm, yyyy] = d.split('.');
      return (dd && mm && yyyy) ? `${yyyy}-${mm}-${dd}` : '';
    }

    // load from server
    async function loadData() {
      try {
        const res = await fetch('/admin/folder_secret_config_editor/data');
        data = await res.json();
        render();
      } catch (err) {
        console.error(err);
      }
    }

    // send delete/update actions
    async function sendAction(payload) {
      await fetch('/admin/folder_secret_config_editor/action', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
      await loadData();
    }

    // delete record after confirmation
    function deleteRec(secret) {
      sendAction({ action: 'delete', secret });
    }

    // build all cards
    function render() {
      const cont = document.getElementById('records');
      cont.innerHTML = '';

      data.forEach(rec => {
        const key = rec.secret;
        const isEdit = editing.has(key);
        const expired = (formatISO(rec.validity) && new Date(formatISO(rec.validity)) < new Date());
        const cls = isEdit ? 'unlocked' : 'locked';

        // outer card
        const wrapper = document.createElement('div');
        wrapper.className = 'card mb-3';
        wrapper.dataset.secret = key;

        // Card header for collapse toggle
        const cardHeader = document.createElement('div');
        cardHeader.className = 'card-header';
        cardHeader.style.cursor = 'pointer';
        const collapseId = `collapse-${key}`;
        cardHeader.setAttribute('data-bs-toggle', 'collapse');
        cardHeader.setAttribute('data-bs-target', `#${collapseId}`);
        cardHeader.setAttribute('aria-expanded', 'false');
        cardHeader.setAttribute('aria-controls', collapseId);
        
        const headerTitle = document.createElement('div');
        headerTitle.className = 'd-flex justify-content-between align-items-center';
        const folderNames = rec.folders.map(f => f.foldername).join(', ');
        headerTitle.innerHTML = `<strong>Ordner: ${folderNames}${expired ? ' <span class="text-danger fw-bold"> ! abgelaufen !</span>' : ''}</strong><i class="bi bi-chevron-down"></i>`;
        cardHeader.appendChild(headerTitle);
        wrapper.appendChild(cardHeader);

        // Collapsible body
        const collapseDiv = document.createElement('div');
        collapseDiv.className = 'collapse';
        collapseDiv.id = collapseId;
        
        const body = document.createElement('div');
        body.className = `card-body ${cls}`;

        // Create row for two-column layout (only if not editing)
        if (!isEdit) {
          const topRow = document.createElement('div');
          topRow.className = 'row mb-3';
          
          // Left column for secret and validity
          const leftCol = document.createElement('div');
          leftCol.className = 'col-md-8';
          
          // secret input
          const secDiv = document.createElement('div');
          secDiv.className = 'mb-2';
          secDiv.innerHTML = `Secret: `;
          const secInput = document.createElement('input');
          secInput.className = 'form-control';
          secInput.type = 'text';
          secInput.value = rec.secret;
          secInput.readOnly = true;
          secInput.dataset.field = 'secret';
          secDiv.appendChild(secInput);
          leftCol.appendChild(secDiv);

          // validity input
          const valDiv = document.createElement('div');
          valDiv.className = 'mb-2';
          valDiv.innerHTML = `Gültig bis: `;
          const valInput = document.createElement('input');
          valInput.className = 'form-control';
          valInput.type = 'date';
          valInput.value = formatISO(rec.validity);
          valInput.readOnly = true;
          valInput.dataset.field = 'validity';
          valDiv.appendChild(valInput);
          leftCol.appendChild(valDiv);
          
          topRow.appendChild(leftCol);
          
          // Right column for QR code
          const rightCol = document.createElement('div');
          rightCol.className = 'col-md-4 text-center';
          
          const qrImg = document.createElement('img');
          qrImg.className = 'qr-code';
          qrImg.style.maxWidth = '200px';
          qrImg.style.width = '100%';
          qrImg.style.border = '1px solid #ddd';
          qrImg.style.padding = '10px';
          qrImg.style.borderRadius = '5px';
          qrImg.alt = 'QR Code';
          generateQRCode(key, qrImg);
          rightCol.appendChild(qrImg);
          
          topRow.appendChild(rightCol);
          body.appendChild(topRow);
        } else {
          // When editing, show fields vertically without QR code
          // secret input
          const secDiv = document.createElement('div');
          secDiv.className = 'mb-2';
          secDiv.innerHTML = `Secret: `;
          const secInput = document.createElement('input');
          secInput.className = 'form-control';
          secInput.type = 'text';
          secInput.value = rec.secret;
          secInput.readOnly = false;
          secInput.dataset.field = 'secret';
          secDiv.appendChild(secInput);
          body.appendChild(secDiv);

          // validity input
          const valDiv = document.createElement('div');
          valDiv.className = 'mb-2';
          valDiv.innerHTML = `Gültig bis: `;
          const valInput = document.createElement('input');
          valInput.className = 'form-control';
          valInput.type = 'date';
          valInput.value = formatISO(rec.validity);
          valInput.readOnly = false;
          valInput.dataset.field = 'validity';
          valDiv.appendChild(valInput);
          body.appendChild(valDiv);
        }

        // folders
        const folderHeader = document.createElement('h6');
        folderHeader.textContent = 'Ordner';
        body.appendChild(folderHeader);

        rec.folders.forEach((f, i) => {
          const fwrap = document.createElement('div');
          fwrap.style = 'border:1px solid #ccc; padding:10px; margin-bottom:10px; border-radius:5px;';

          // name
          fwrap.appendChild(document.createTextNode("Ordnername: "));
          const nameGroup = document.createElement('div');
          nameGroup.className = 'input-group mb-2';
          const nameInput = document.createElement('input');
          nameInput.className = 'form-control';
          nameInput.type = 'text';
          nameInput.value = f.foldername;
          nameInput.readOnly = !isEdit;
          nameInput.dataset.field = `foldername-${i}`;
          nameGroup.appendChild(nameInput);

          if (isEdit) {
            const remBtn = document.createElement('button');
            remBtn.className = 'btn btn-outline-danger';
            remBtn.type = 'button';
            remBtn.textContent = 'entfernen';
            remBtn.addEventListener('click', () => removeFolder(key, i));
            nameGroup.appendChild(remBtn);
          }
          fwrap.appendChild(nameGroup);

          // path
          fwrap.appendChild(document.createTextNode("Ordnerpfad: "));
          const pathInput = document.createElement('input');
          pathInput.className = 'form-control mb-2';
          pathInput.type = 'text';
          pathInput.value = f.folderpath;
          pathInput.readOnly = !isEdit;
          pathInput.dataset.field = `folderpath-${i}`;
          fwrap.appendChild(pathInput);

          body.appendChild(fwrap);
        });

        if (isEdit) {
          const addFld = document.createElement('button');
          addFld.className = 'btn btn-sm btn-primary mb-2';
          addFld.type = 'button';
          addFld.textContent = 'Ordner hinzufügen';
          addFld.addEventListener('click', () => addFolder(key));
          body.appendChild(addFld);
        }

        // actions row
        const actions = document.createElement('div');

        if (!isEdit) {
          const openButton = document.createElement('button');
          openButton.className = 'btn btn-secondary btn-sm me-2';
          openButton.onclick = () => window.open(`/?secret=${rec.secret}`, '_self');
          openButton.textContent = 'Link öffnen';
          actions.appendChild(openButton);
        }

        if (!isEdit) {
          const openButton = document.createElement('button');
          openButton.className = 'btn btn-secondary btn-sm me-2';
            openButton.onclick = () => toClipboard(`${window.location.origin}/?secret=${rec.secret}`);
          openButton.textContent = 'Link kopieren';
          actions.appendChild(openButton);
        }

        const delBtn = document.createElement('button');
        delBtn.className = 'btn btn-danger btn-sm me-2 delete-btn';
        delBtn.type = 'button';
        delBtn.textContent = 'löschen';
        delBtn.dataset.secret = key;
        actions.appendChild(delBtn);

        const cloneBtn = document.createElement('button');
        cloneBtn.className = 'btn btn-secondary btn-sm me-2';
        cloneBtn.type = 'button';
        cloneBtn.textContent = 'clonen';
        cloneBtn.addEventListener('click', () => cloneRec(key));
        actions.appendChild(cloneBtn);

        if (isEdit || expired) {
          const renewBtn = document.createElement('button');
          renewBtn.className = 'btn btn-info btn-sm me-2';
          renewBtn.type = 'button';
          renewBtn.textContent = 'erneuern';
          renewBtn.addEventListener('click', () => renewRec(key));
          actions.appendChild(renewBtn);
        }

        if (isEdit) {
          const saveBtn = document.createElement('button');
          saveBtn.className = 'btn btn-success btn-sm me-2';
          saveBtn.type = 'button';
          saveBtn.textContent = 'speichern';
          saveBtn.addEventListener('click', () => saveRec(key));
          actions.appendChild(saveBtn);
          
          const cancelBtn = document.createElement('button');
          cancelBtn.className = 'btn btn-secondary btn-sm';
          cancelBtn.type = 'button';
          cancelBtn.textContent = 'abbrechen';
          cancelBtn.addEventListener('click', () => cancelEdit(key));
          actions.appendChild(cancelBtn);
        }

        body.appendChild(actions);
        collapseDiv.appendChild(body);
        wrapper.appendChild(collapseDiv);
        cont.appendChild(wrapper);
      });
    }

    // generate a unique secret
    function generateSecret(existing) {
      let s;
      do {
        s = Array.from({length:32}, () => ALPHABET[Math.floor(Math.random()*ALPHABET.length)]).join('');
      } while (existing.includes(s));
      return s;
    }

    // CRUD helpers
    function cancelEdit(secret) {
      editing.delete(secret);
      // If this was a new record that was never saved, remove it
      const originalExists = data.some(r => r.secret === secret && !editing.has(secret));
      loadData(); // Reload to discard changes
    }
    function cloneRec(secret) {
      const idx = data.findIndex(r => r.secret === secret);
      const rec = JSON.parse(JSON.stringify(data[idx]));
      const existing = data.map(r => r.secret);
      rec.secret = generateSecret(existing);
      const futureDate = new Date();
      futureDate.setDate(futureDate.getDate() + 35);
      // Format as DD.MM.YYYY for validity input
      const dd = String(futureDate.getDate()).padStart(2, '0');
      const mm = String(futureDate.getMonth() + 1).padStart(2, '0');
      const yyyy = futureDate.getFullYear();
      rec.validity = `${dd}.${mm}.${yyyy}`;
      data.splice(idx+1, 0, rec);
      editing.add(rec.secret);
      render();
      // Auto-expand the cloned item
      setTimeout(() => {
        const collapseEl = document.getElementById(`collapse-${rec.secret}`);
        if (collapseEl) {
          const bsCollapse = new bootstrap.Collapse(collapseEl, { toggle: false });
          bsCollapse.show();
        }
      }, 100);
    }
    async function renewRec(secret) {
      // find current record
      const rec = data.find(r => r.secret === secret);
      if (!rec) return;

      // generate a fresh unique secret
      const existing = data.map(r => r.secret);
      const newSecret = generateSecret(existing);

      // validity = today + 35 days, formatted as YYYY-MM-DD
      const future = new Date();
      future.setDate(future.getDate() + 35);
      const yyyy = future.getFullYear();
      const mm = String(future.getMonth() + 1).padStart(2, '0');
      const dd = String(future.getDate()).padStart(2, '0');
      const validity = `${yyyy}-${mm}-${dd}`;

      // keep folders unchanged
      const folders = rec.folders.map(f => ({
        foldername: f.foldername,
        folderpath: f.folderpath
      }));

      // persist via existing endpoint
      await sendAction({
        action: 'update',
        oldSecret: secret,
        newSecret,
        validity,
        folders
      });
    }
    function addFolder(secret) {
      data.find(r => r.secret === secret).folders.push({foldername:'', folderpath:''});
      render();
    }
    function removeFolder(secret, i) {
      data.find(r => r.secret === secret).folders.splice(i,1);
      render();
    }

    async function saveRec(secret) {
      const card = document.querySelector(`[data-secret="${secret}"]`);
      const newSecret = card.querySelector('input[data-field="secret"]').value.trim();
      const validity = card.querySelector('input[data-field="validity"]').value;
      const rec = data.find(r => r.secret === secret);
      const folders = rec.folders.map((_, i) => ({
        foldername: card.querySelector(`input[data-field="foldername-${i}"]`).value.trim(),
        folderpath: card.querySelector(`input[data-field="folderpath-${i}"]`).value.trim()
      }));

      if (!newSecret || data.some(r => r.secret !== secret && r.secret === newSecret)) {
        return alert('Secret must be unique and non-empty');
      }
      if (!validity) {
        return alert('Validity required');
      }
      if (folders.some(f => !f.foldername || !f.folderpath)) {
        return alert('Folder entries cannot be empty');
      }

      await sendAction({
        action: 'update',
        oldSecret: secret,
        newSecret,
        validity,
        folders
      });
      editing.delete(secret);
      await loadData();
    }


    let addBtnHandler = null;
    let deleteClickHandler = null;
    let confirmDeleteHandler = null;

    function bindHandlers() {
      const root = document.getElementById('records');
      if (!root || root.dataset.bound) return false;
      root.dataset.bound = '1';

      const dataScript = document.getElementById('folder-config-page-data');
      if (dataScript) {
        try {
          const parsed = JSON.parse(dataScript.textContent || '{}');
          if (Array.isArray(parsed.alphabet)) {
            ALPHABET = parsed.alphabet;
          } else if (typeof parsed.alphabet === 'string') {
            ALPHABET = parsed.alphabet.split('');
          } else {
            ALPHABET = [];
          }
        } catch (err) {
          console.error('Failed to parse folder config data', err);
        }
      }

      addBtnHandler = () => {
        const existing = data.map(r => r.secret);
        const newSecret = generateSecret(existing);
        data.push({ secret: newSecret, validity: new Date().toISOString().slice(0,10), folders: [] });
        editing.add(newSecret);
        render();
        setTimeout(() => {
          const collapseEl = document.getElementById(`collapse-${newSecret}`);
          if (collapseEl) {
            const bsCollapse = new bootstrap.Collapse(collapseEl, { toggle: false });
            bsCollapse.show();
          }
        }, 100);
      };

      const addBtn = document.getElementById('add-btn');
      if (addBtn) addBtn.addEventListener('click', addBtnHandler);

      deleteClickHandler = (e) => {
        if (e.target.matches('.delete-btn')) {
          pendingDelete = e.target.dataset.secret;
          const modal = new bootstrap.Modal(document.getElementById('confirmDeleteModal'));
          modal.show();
        }
      };
      document.addEventListener('click', deleteClickHandler);

      confirmDeleteHandler = () => {
        if (pendingDelete) deleteRec(pendingDelete);
        pendingDelete = null;
        const modal = bootstrap.Modal.getInstance(document.getElementById('confirmDeleteModal'));
        if (modal) modal.hide();
      };
      const confirmBtn = document.querySelector('.confirm-delete');
      if (confirmBtn) confirmBtn.addEventListener('click', confirmDeleteHandler);

      return true;
    }

    function unbindHandlers() {
      const addBtn = document.getElementById('add-btn');
      if (addBtn && addBtnHandler) addBtn.removeEventListener('click', addBtnHandler);
      addBtnHandler = null;

      if (deleteClickHandler) document.removeEventListener('click', deleteClickHandler);
      deleteClickHandler = null;

      const confirmBtn = document.querySelector('.confirm-delete');
      if (confirmBtn && confirmDeleteHandler) confirmBtn.removeEventListener('click', confirmDeleteHandler);
      confirmDeleteHandler = null;
    }

    function initFolderConfigPage() {
      data = [];
      editing = new Set();
      pendingDelete = null;

      if (!bindHandlers()) return;
      loadData();
    }

    function destroyFolderConfigPage() {
      unbindHandlers();
    }

    if (window.PageRegistry && typeof window.PageRegistry.register === 'function') {
      window.PageRegistry.register('folder_secret_config', {
        init: initFolderConfigPage,
        destroy: destroyFolderConfigPage
      });
    }

})();
