{% extends 'base.html' %}

{% block content %}
    <span id="user-id">
        {% if request.user.is_authenticated %}
            User: {{ request.user }}
        {% else %}
            CID: {{ cid }}
        {% endif %}
    </span>

    {% include "exam_clock.html" %}

    <div class="no-select">
        <div class="d-flex justify-content-between align-items-start">
            <h2 class="mb-0">
                {{ exam }}: Question
                [<span id="question-number">{{ pos|add:1 }}</span>/<span id="exam-length">{{ exam_length }}</span>]
            </h2>
            <div class="ms-3">
                <!-- flag button moved into the question fragment so it updates with HTMX swaps -->
            </div>
        </div>

        {% if exam.publish_results %}
            <div class="alert alert-primary review-mode-alert" role="alert">
                Exam is in review mode. Add question feedback
                <a href="#" onclick="return window.create_popup_window('{% url "feedback_create" question_type="physics" pk=question.pk %}')">here</a>.
            </div>
        {% elif cid_user_exam.completed %}
            <div class="alert alert-primary review-mode-alert" role="alert">
                Exam completed.
            </div>
        {% endif %}

        <div>
            <p><span id="question-stem">{{ question.stem|safe }}</span></p>
        </div>


        <div id="question-fragment"
             hx-trigger="load"
             hx-swap="innerHTML"
             hx-get="{% if cid %}{% url 'physics:exam_take_fragment' pk=exam.pk sk=pos cid=cid passcode=passcode %}{% else %}{% url 'physics:exam_take_fragment_user' pk=exam.pk sk=pos %}{% endif %}">
            <!-- HTMX will load the question form + controls here -->
        </div>
    </div>

    <h4>Questions</h4>
    <div id="menu-list"></div>



    {% include "physics/exam_take_help.html" %}

{% endblock %}

{# HTMX fragment will load question-specific JS; nothing required here #}

{% block css %}
    <style type="text/css">
        /* Color variables and dark-mode support
           - Uses CSS variables for easy theming
           - Honors system preference via prefers-color-scheme
           - Also supports a manual `.dark-mode` class on body or a parent
        */


        :root {
            --bg: #050607;
            --text: #e6eef6;
            --muted: #9aa4ad;
            --card-bg: #0f1720;
            --card-border: #1f2a33;
            --primary: #6ea8ff;
            --success: #36d07a;
            --danger: #ff6b6b;
            --feedback-bg: #071322;
            --shadow: 0 2px 6px rgba(0,0,0,0.6);
        }
        body, .exam-take-container { background: var(--bg); color: var(--text); }

        /* Manual override: add `dark-mode` to body or a parent to force dark theme */
        body.dark-mode, .dark-mode { color: var(--text); background: var(--bg); }

        /* Layout and responsiveness */
        .exam-take-container { max-width: 980px; margin: 0 auto; padding: 1rem; }
        .no-select { user-select: none; }

        .flex-container { display: flex; align-items: center; gap: 0.75rem; }
          /* fieldWrapper is used around each label + input; ensure it stretches the full width */
        .fieldWrapper { width: 100%; display: flex; align-items: center; gap: 0.75rem; }

          /* We keep two main columns inside each fieldWrapper:
              - the label (question-text) which should take the bulk of space and sit to the left on wide screens
              - the input container (.flex-1) which holds the input and a post-input label; the post-input should float right
          */
        .flex-8 { flex: 8; }
        .flex-1 { flex: 1; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }

             /* Left-align label text on wide screens so the question text appears on the left, input between, and the
                 post-input label floats to the right. Padding keeps visual separation. */
        .question-text { margin: 0; text-align: left; padding-right: 0.5rem; }

        /* Answer items styled as cards */
        .physics-answer-list { list-style: none; padding: 0; margin: 0; }
        .physics-answer-list li {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            padding: 0.75rem 1rem;
            border: 1px solid var(--card-border);
            border-radius: 0.5rem;
            background: var(--card-bg);
            box-shadow: var(--shadow);
            color: var(--text);
        }
        .physics-answer-list li + li { margin-top: 0.75rem; }

        .question-text { margin: 0; }

        /* Post-input badge (shows True/False text next to inputs) */
        .postinput { display: inline-block; min-width: 3rem; text-align: right; color: var(--muted); }
        .physics-answer-list input { margin: 0 0.25rem 0 0; }
        /* show a compact post-label on the right of the input container */
        .physics-answer-list input:checked + .postinput::after {
            content: 'True'; color: var(--success); font-weight: 600; margin-left: 0.4rem;
        }
        .physics-answer-list input:not(:checked) + .postinput::after {
            content: 'False'; color: var(--muted); font-weight: 600; margin-left: 0.4rem;
        }

        /* Correctness badges and highlights */
        .answer-true::before,
        .answer-false::before {
            display: inline-block;
            margin-left: auto;
            padding: 0.18rem 0.5rem;
            border-radius: 0.25rem;
            font-size: 0.75rem;
            font-weight: 600;
            color: #fff;
        }
        .answer-true::before { content: "Correct"; background: var(--success); }
        .answer-false::before { content: "Not correct"; background: var(--muted); }

        .answer-correct { background-color: rgba(25,135,84,0.06); border-color: rgba(25,135,84,0.18); }
        .answer-incorrect { background-color: rgba(220,53,69,0.04); border-color: rgba(220,53,69,0.12); }

        /* Feedback block */
        .feedback {
            padding: 0.85rem 1rem;
            display: block;
            margin-top: 0.5rem;
            border-left: 4px solid var(--primary);
            background: var(--feedback-bg);
            color: var(--text);
            border-radius: 0.25rem;
        }

        /* Question menu (jump buttons) */
        #menu-list { margin-top: 1rem; display:flex; flex-wrap:wrap; gap:0.4rem; }
        button.question-menu-item {
            padding: 0.35rem 0.6rem;
            border-radius: 0.35rem;
            border: 1px solid var(--card-border);
            background: var(--card-bg);
            color: var(--text);
            cursor: pointer;
            font-size: 0.9rem;
        }
        button.question-menu-item.current-question {
            background: var(--primary); color: #fff; border-color: var(--primary);
            box-shadow: 0 1px 3px rgba(13,110,253,0.18);
        }

        /* Control buttons spacing */
        .mt-2 .save { margin-right: 0.5rem; }
        .mt-2 .save.btn.btn-default { background: var(--feedback-bg); border: 1px solid var(--card-border); color: var(--text); }

    /* Overview button - make it stand out using the primary color */
        #overview-button { background: var(--primary); border-color: var(--primary); color: #fff; }
        #overview-button:hover { filter: brightness(0.95); box-shadow: 0 3px 8px rgba(13,110,253,0.18); }

    /* Previous / Next button colors */
        .mt-2 button[name="previous"] { background: var(--info); border-color: var(--info); color: #fff; }
        .mt-2 button[name="previous"]:hover { filter: brightness(0.95); box-shadow: 0 2px 6px rgba(0,0,0,0.08); }

        .mt-2 button[name="next"] { background: var(--info); border-color: var(--info); color: #fff; }
        .mt-2 button[name="next"]:hover { filter: brightness(0.95); box-shadow: 0 3px 8px rgba(13,110,253,0.18); }

        /* Small helper: make labels wrap nicely on small screens */
        @media (max-width: 576px) {
            /* On small screens, stack the label and input for readability */
            .flex-container { flex-direction: column; align-items: stretch; }
            .fieldWrapper { flex-direction: column; align-items: stretch; }
            .question-text { text-align: left; padding-right: 0; margin-bottom: 0.4rem; }
            .flex-1 { justify-content: flex-start; gap: 0.5rem; }
            .postinput { margin-top: 0.4rem; text-align: left; }
            .physics-answer-list li { padding: 0.6rem; }
        }
            /* Question menu item states (small pill buttons) */
        button.question-menu-item {
            color: var(--text);
            border: 1px solid var(--card-border);
            background: var(--card-bg);
            padding: 0.25rem 0.5rem;
            border-radius: 0.35rem;
            display: inline-flex;
            align-items: center;
            gap: 0.4rem;
        }
        button.question-menu-item.answered {
            border-color: var(--success) !important; /* answered -> success border */
        }
            /* flagged items show an icon only; no border change here */
        button.question-menu-item .question-flag {
            margin-left: 0.25rem;
            font-size: 0.85em;
            color: #ffc107;
            line-height: 1;
        }
        /* Loading blur + spinner for question fragment */
        #question-fragment.loading { filter: blur(3px); opacity: 0.9; pointer-events: none; position: relative; }
        #question-fragment .loading-spinner {
            position: absolute;
            left: 50%; top: 50%; transform: translate(-50%, -50%);
            width: 36px; height: 36px; border-radius: 50%;
            border: 4px solid rgba(255,255,255,0.2); border-top-color: var(--primary);
            animation: spin 800ms linear infinite; z-index: 1200;
        }
        @keyframes spin { from { transform: translate(-50%,-50%) rotate(0deg); } to { transform: translate(-50%,-50%) rotate(360deg); } }
    </style>
{% endblock %}

{% block head_js %}{% endblock %}

{% block js %}
    <script>
/* HTMX swap helpers: preserve scroll and container height to avoid page jumping
     Listens for htmx:beforeSwap and htmx:afterSwap on the question fragment container.
*/
        (function(){
            function getTarget(evt){
                return (evt.detail && (evt.detail.target || evt.detail.elt)) || evt.target;
            }

            document.addEventListener('htmx:beforeSwap', function(evt){
                try{
                    var target = getTarget(evt);
                    if(!target || target.id !== 'question-fragment') return;
            // save scroll position
                    target.__savedScrollY = window.scrollY || window.pageYOffset || 0;
            // preserve current height to avoid layout shift while fragment is swapping
                    target.style.minHeight = target.offsetHeight + 'px';
                }catch(e){ console && console.error && console.error(e); }
            });

            document.addEventListener('htmx:afterSwap', function(evt){
                try{
                    var target = getTarget(evt);
                    if(!target || target.id !== 'question-fragment') return;
                    var y = target.__savedScrollY;
                    if(typeof y === 'number') window.scrollTo(0, y);
            // remove the minHeight after a short delay to allow content to layout
                    setTimeout(function(){ target.style.minHeight = ''; }, 60);
            // notify fragment-loaded so fragment init code can listen if required
                    target.dispatchEvent(new CustomEvent('fragment:loaded', { bubbles: true }));
                }catch(e){ console && console.error && console.error(e); }
            });
        })();
    </script>
    <script>
// Global listener for server-triggered save confirmations.
// The view sets an `HX-Trigger` header named `saved` when an HTMX save occurs.
        document.addEventListener('saved', function(evt){
            try {
                // Update the question list state locally so the menu reflects answered questions
                try {
                    var pos = (typeof window.currentQuestionPos === 'number') ? window.currentQuestionPos : (document.getElementById('question-number') ? parseInt(document.getElementById('question-number').textContent, 10) - 1 : NaN);
                    if (!isNaN(pos)) {
                        window.examQuestionAnswered = window.examQuestionAnswered || new Array({{ exam_length }}).fill(false);
                        window.examQuestionAnswered[pos] = true;
                        if(typeof window.updateQuestionMenu === 'function'){
                            window.updateQuestionMenu();
                        } else {
                            var btn = document.querySelector('#menu-list [data-qn="' + pos + '"]');
                            if (btn) btn.classList.add('answered');
                        }
                    }
                } catch (e) { console && console.error && console.error(e); }
            } catch (e) { console && console.error && console.error(e); }
        });
    </script>
    <script>
        // Minimal per-question status injected by view: answered/flagged arrays
        window.examQuestionAnswered = {{ answered_json|safe }};
        window.examQuestionFlagged = {{ flagged_json|safe }};
        // Update the visual state of the question menu based on global arrays
        window.updateQuestionMenu = function(){
            console.log("Updating question menu");
            try{
                const answered = window.examQuestionAnswered || [];
                const flagged = window.examQuestionFlagged || [];
                const pos = (typeof window.currentQuestionPos === 'number') ? window.currentQuestionPos : NaN;
                document.querySelectorAll('#menu-list .question-menu-item').forEach(btn => {
                    const idx = parseInt(btn.dataset.qn, 10);
                    btn.classList.toggle('answered', !!answered[idx]);
                    btn.classList.toggle('flagged', !!flagged[idx]);
                    btn.classList.toggle('current-question', idx === pos);
                    // manage flag icon presence
                    const hasIcon = btn.querySelector('.question-flag') !== null;
                    if (flagged[idx] && !hasIcon) {
                        const el = document.createElement('span'); el.className = 'question-flag'; el.setAttribute('aria-hidden','true'); el.textContent = '⚑'; btn.appendChild(el);
                    } else if (!flagged[idx] && hasIcon) {
                        const el = btn.querySelector('.question-flag'); if(el) el.remove();
                    }
                });
            }catch(e){ console && console.error && console.error(e); }
        };
    </script>
    <script>
            // Show a blur + spinner on the question fragment while HTMX loads it
        (function(){
            function showLoading(){
                try{
                    const frag = document.getElementById('question-fragment');
                    if(!frag) return;
                    frag.classList.add('loading');
                    if(!frag.querySelector('.loading-spinner')){
                        const s = document.createElement('div');
                        s.className = 'loading-spinner';
                        s.setAttribute('aria-hidden','true');
                        frag.appendChild(s);
                    }
                }catch(e){console && console.error && console.error(e);}
            }

            function hideLoading(){
                try{
                    const frag = document.getElementById('question-fragment');
                    if(!frag) return;
                    frag.classList.remove('loading');
                    const s = frag.querySelector('.loading-spinner'); if(s) s.remove();
                }catch(e){console && console.error && console.error(e);}
            }

            document.body.addEventListener('htmx:beforeRequest', function(evt){
                try{
                    const target = (evt.detail && (evt.detail.target || evt.detail.elt)) || evt.target;
                        // if the request targets the question fragment, show loading
                    if(target && (target.id === 'question-fragment' || (target.closest && target.closest('#question-fragment')))){
                        showLoading();
                    }
                }catch(e){/* ignore */}
            });

            document.body.addEventListener('htmx:afterSwap', function(evt){
                try{
                    const target = (evt.detail && (evt.detail.target || evt.detail.elt)) || evt.target;
                    if(target && (target.id === 'question-fragment' || (target.closest && target.closest('#question-fragment')))){
                        hideLoading();
                    }
                }catch(e){}
            });

                // also hide after settle to be safe
            document.body.addEventListener('htmx:afterSettle', function(evt){ hideLoading(); });
        })();
    </script>
    <script>
            // Also update after HTMX settle to ensure DOM changes are applied
        document.body.addEventListener('htmx:afterSettle', function(){
            try{ if(typeof window.updateQuestionMenu === 'function') window.updateQuestionMenu(); }catch(e){}
        });
    </script>
    <script>
        // Listen for flag button swaps (HTMX) and update the local menu state
        document.addEventListener('htmx:afterSwap', function(evt){
            try{
                // read the current flag button in DOM (safer than relying on event target)
                var container = document.getElementById('flag-button-container');
                if(!container) return;
                var btn = container.querySelector('button');
                if(!btn) return;
                var flaggedNow = btn.classList.contains('btn-warning');
                var pos = (typeof window.currentQuestionPos === 'number') ? window.currentQuestionPos : NaN;
                if(!isNaN(pos)){
                    window.examQuestionFlagged = window.examQuestionFlagged || new Array({{ exam_length }}).fill(false);
                    window.examQuestionFlagged[pos] = !!flaggedNow;
                    if(typeof window.updateQuestionMenu === 'function') window.updateQuestionMenu();
                }
            }catch(e){ console && console.error && console.error(e); }
        });
    </script>
{% endblock %}
