/**
 * Dynamic security‑question UI
 * --------------------------------------------------------------
 * This module builds a progressive “question / answer” form.
 * Users pick a question from a dropdown, type an answer,
 * press Enter, and a new row appears until all options are exhausted.
 *
 * When the last option is answered the hidden fields are assembled
 * inside #qa‑map‑container ready for form submission.
 *
 */
(() => {
    /** --------------------------------------------------------------------
     *  State
     * -------------------------------------------------------------------- */
    const answersMap = {};          
    let currentRow = null;         // Row currently being edited
    let pairCounter = 1;           // Incremental ID for data‑attributes

    /** --------------------------------------------------------------------
     *  Helper Functions
     * -------------------------------------------------------------------- */

    /**
     * Clone the question‑component template.
     * @returns {DocumentFragment}
     */
    const getQaFragment = () => {
        const tmpl = document.getElementById('question-component-template');
        return document.importNode(tmpl.content, true);
    };

    /**
     * Retrieve the SELECT and INPUT elements from a fragment.
     * @param {DocumentFragment} frag
     * @returns {{select: HTMLSelectElement, input: HTMLInputElement}}
     */
    const getSelectAndInput = (frag) => ({
        select: frag.querySelector('#question-component'),
        input: frag.querySelector('#answer-component')
    });

    /**
     * Create a fresh row container from the row template.
     * @returns {HTMLDivElement}  // <div class="qa-row-container">
     */
    const createRow = () => {
        const tmpl = document.getElementById('qa-row-template');
        const frag = document.importNode(tmpl.content, true);
        return frag.querySelector('div.qa-row-container');
    };

    /**
     * Append the SELECT and INPUT controls to a given row.
     * @param {HTMLDivElement} row
     * @param {HTMLSelectElement} select
     * @param {HTMLInputElement} input
     */
    const appendComponents = (row, select, input) => {
        row.querySelector('.question-area').appendChild(select);
        row.querySelector('.answer-area').appendChild(input);
    };

    /**
     * Build the hidden‑field markup for a single Q/A pair.
     *
     * @param {string} encodedQuestion   // already URL‑safe Base64
     * @param {string} answer
     * @returns {HTMLDivElement}        // <div class="answer">…</div>
     */
    const buildAnswerDiv = (encodedQuestion, answer) => {
        const div = document.createElement('div');
        div.className = 'answer';

        const qInput = document.createElement('input');
        qInput.type = 'hidden';
        qInput.name = 'questions';
        qInput.value = encodedQuestion;

        const aInput = document.createElement('input');
        aInput.type = 'hidden';
        aInput.name = 'answers';
        aInput.value = answer;

        div.appendChild(qInput);
        div.appendChild(aInput);
        return div;
    };

    /**
     * Reset UI after an answer is recorded:
     *   1. Remove the answered option from the SELECT.
     *   2. Clear the INPUT value.
     *   3. Hide both controls if no options remain.
     *
     * @param {HTMLSelectElement} select
     * @param {HTMLInputElement} input
     * @param {number} removedIdx  – index of the option that must disappear
     */
    const resetSelectAndInput = (select, input, removedIdx) => {
        // 1. Remove the chosen option.
        if (removedIdx >= 0 && removedIdx < select.options.length) {
            select.remove(removedIdx);
        }

        // 2. Clear the answer field.
        input.value = '';

        // 3. Hide controls when the dropdown is empty.
        const hide = select.options.length === 0;
        select.classList.toggle('d-none', hide);
        input.classList.toggle('d-none', hide);
    };

    /**
     * Insert a brand‑new row after the current one and focus its INPUT.
     *
     * @param {HTMLSelectElement} select
     * @param {HTMLInputElement} input
     * @returns {HTMLDivElement} newly created row
     */
    const addNewRow = (select, input) => {
        const nextRow = createRow();
        appendComponents(nextRow, select, input);
        document.getElementById('questions-wrapper').appendChild(nextRow);
        input.focus();
        return nextRow;
    };

    /**
     * Populate the hidden‑field container (#qa‑map‑container) with all
     * collected Q/A pairs, ready for form submission.
     */
    const prepareQuestionAnswersForSubmit = () => {
        const container = document.getElementById('qa-map-container');
        container.replaceChildren(); // clear any previous markup

        for (const encodedQ in answersMap) {
            const answerDiv = buildAnswerDiv(encodedQ, answersMap[encodedQ]);
            container.appendChild(answerDiv);
        }
    };

    /**
     * Core routine triggered when the user presses Enter in the answer INPUT.
     * It records the selected question + typed answer, updates the UI,
     * and either creates a new row or finalises the hidden‑field map.
     *
     * @param {HTMLSelectElement} select
     * @param {HTMLInputElement} input
     * @returns {HTMLDivElement|null} the next row to edit, or null if finished
     */
    const acceptAnswer = (select, input) => {
        const chosenIdx = select.selectedIndex;
        const chosenOption = select.options[chosenIdx];

        // Guard: nothing selected or answer empty → ignore.
        if (!chosenOption || !input.value.trim()) return null;

        // ----- Populate the visible labels in the current row -----
        const qLabel = currentRow.querySelector('.question');
        qLabel.textContent = chosenOption.text;
        qLabel.classList.remove('d-none');
        qLabel.dataset.index = pairCounter;

        const answer = input.value.trim();
        const aLabel = currentRow.querySelector('.answer');
        aLabel.textContent = answer;
        aLabel.classList.remove('d-none');
        aLabel.dataset.index = pairCounter;

        // ----- Store the pair internally -----
        answersMap[chosenOption.value] = answer;
        pairCounter++;

        // ----- Clean up the UI (remove used option, clear input) -----
        resetSelectAndInput(select, input, chosenIdx);

        // ----- Either add a fresh row or finish up -----
        if (select.options.length) {
            // Still options left -> start a new row.
            return addNewRow(select, input);
        } else {
            // No more options -> assemble hidden fields.
            prepareQuestionAnswersForSubmit();
			// All done submit form
			document.getElementById('securityQuestionSubmit').click(); 
            return null;
        }
    };

    /** --------------------------------------------------------------------
     *  Initialisation (runs once DOM is ready)
     * -------------------------------------------------------------------- */
    document.addEventListener('DOMContentLoaded', () => {
        // 1. Create the very first editable row.
        const firstRow = createRow();
        document.getElementById('questions-wrapper').appendChild(firstRow);

		// 2. Pull a fresh SELECT + INPUT from the component template.
        const { select, input } = getSelectAndInput(getQaFragment());
        appendComponents(firstRow, select, input);

        // 3. Track the row we are currently editing.
        currentRow = firstRow;

        // ---------------------------------------------------------------
        // ENTER‑key handling on the answer INPUT
        // ---------------------------------------------------------------
        input.addEventListener('keydown', (e) => {
            if (e.key !== 'Enter') return; // ignore other keys

            e.preventDefault(); // stop native form submit
            // Record the answer and move to the next row (if any).
            currentRow = acceptAnswer(select, input);
        });

        // Focus the input straight away for a smooth UX.
        input.focus();
		
		// Scroll it into view – smooth animation, align to nearest edge
		// Options: block = "center"/"start"/"end", inline = "nearest"
		input.scrollIntoView({ behavior: 'smooth', block: 'center' });
    });

    /** --------------------------------------------------------------------
     *  Defensive form‑submission guard
     *  (covers the case where the user clicks the Submit button before
     *   pressing Enter on the final row)
     * -------------------------------------------------------------------- */
    const form = document.getElementById('securityQuestionForm');
    form?.addEventListener('submit', (e) => {
        // If the submit event wasn't triggered by a button (e.g. Enter on a
        // non‑input element), block it – the UI expects explicit button press.
        if (e.submitter === undefined) {
            e.preventDefault();
            console.info('Form blocked – press the button to submit.');
            return;
        }
		
		JadaptiveUtils.startAwesomeSpin($('#securityQuestionSubmit i'), 'fa-sign-in-alt');

        // Grab the *original* SELECT/INPUT that belong to the last row.
        const select = document.getElementById('question-component');
        const input = document.getElementById('answer-component');

        // Edge case: exactly one option remains – the user may have typed
        // the answer and clicked Submit without hitting Enter.
        if (select.options.length === 1) {
            const chosenIdx = select.selectedIndex;
            const chosenOption = select.options[chosenIdx];
            const answerInInput = input.value.trim();

            // If we haven't stored this pair yet, capture it now.
            if (chosenOption && answerInInput && !answersMap[chosenOption.value]) {
                // Re‑use the same logic as the Enter‑key path.
                currentRow = acceptAnswer(select, input);
            }
        }

        console.info('Form submitted via button:', e.submitter);
    });
})();