#!/usr/bin/env python3
"""
LMS Academy Module v1.0
JvG Consultancy — HSEQ Intelligence Dashboard
Flask module: User portal, Admin portal, Quiz engine, Compliance matrix
All routes prefixed /lms/ — register via app.register_blueprint(lms_bp) or direct import.
"""

import os
import json
import uuid
import sqlite3
from datetime import datetime, date, timedelta

from flask import (
    Blueprint, request, render_template_string, redirect, url_for,
    jsonify, session
)

# ── Config ───────────────────────────────────────────────────────────────────
BASE_PATH = os.environ.get('BASE_PATH', '/hseq-dashboard')
DB_PATH = os.environ.get('LMS_DB_PATH', '/root/projects/jg/HSEQ-Intelligence-Monitor/app/hseq_kennisbank.db')

lms_bp = Blueprint('lms', __name__, url_prefix='/lms')

# Try to use existing get_db from search module; fallback to direct connection
try:
    import sys, importlib
    _app_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)))
    if _app_dir not in sys.path:
        sys.path.insert(0, _app_dir)
    from search import get_db as _get_db
    def get_db():
        return _get_db()
except Exception:
    def get_db():
        conn = sqlite3.connect(DB_PATH)
        conn.row_factory = sqlite3.Row
        return conn

# ── Helpers ──────────────────────────────────────────────────────────────────

def _current_employee_id():
    """Stub: returns first active employee. Replace with real session auth."""
    conn = get_db()
    try:
        r = conn.execute("SELECT id FROM employees WHERE status='active' ORDER BY id LIMIT 1").fetchone()
        return r['id'] if r else 1
    finally:
        conn.close()


def _base_css():
    return """
    :root{--primary:#003366;--primary-light:#1a5276;--success:#00A859;--warning:#F59E0B;--danger:#EF4444;--bg:#F3F4F6;--card:#fff;--text:#1F2937;--text-muted:#6B7280;--border:#E5E7EB}
    *{box-sizing:border-box;margin:0;padding:0}
    body{font-family:'Segoe UI',system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.6}
    .container{max-width:1200px;margin:0 auto;padding:20px}
    h1{font-size:1.5rem;font-weight:700;color:var(--primary);margin-bottom:16px}
    h2{font-size:1.2rem;font-weight:600;color:var(--primary);margin:20px 0 12px}
    .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-bottom:24px}
    .card{background:var(--card);border-radius:10px;padding:20px;box-shadow:0 1px 3px rgba(0,0,0,.08)}
    .card .label{font-size:.75rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}
    .card .value{font-size:1.8rem;font-weight:700;color:var(--primary)}
    .card.success .value{color:var(--success)}
    .card.warning .value{color:var(--warning)}
    .card.danger .value{color:var(--danger)}
    table{width:100%;border-collapse:collapse;background:var(--card);border-radius:8px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,.08)}
    th,td{padding:10px 14px;text-align:left;font-size:.85rem;border-bottom:1px solid var(--border)}
    th{background:var(--primary);color:#fff;font-weight:600;font-size:.75rem;text-transform:uppercase;letter-spacing:.5px}
    tr:hover{background:#f0f4ff}
    .badge{display:inline-block;padding:2px 10px;border-radius:12px;font-size:.7rem;font-weight:600}
    .badge-success{background:#d1fae5;color:#065f46}
    .badge-warning{background:#fef3c7;color:#92400e}
    .badge-danger{background:#fee2e2;color:#991b1b}
    .badge-info{background:#dbeafe;color:#1e40af}
    .badge-muted{background:#e5e7eb;color:#4b5563}
    .progress-bar{background:#e5e7eb;border-radius:6px;height:8px;overflow:hidden}
    .progress-fill{height:100%;border-radius:6px;background:var(--success);transition:width .3s}
    .btn{display:inline-block;padding:8px 18px;border-radius:6px;font-size:.85rem;font-weight:600;text-decoration:none;border:none;cursor:pointer;transition:all .15s}
    .btn-primary{background:var(--primary);color:#fff}
    .btn-primary:hover{background:var(--primary-light)}
    .btn-success{background:var(--success);color:#fff}
    .btn-danger{background:var(--danger);color:#fff}
    .btn-warning{background:var(--warning);color:#fff}
    .btn-sm{padding:5px 12px;font-size:.75rem}
    .tabs{display:flex;gap:4px;margin-bottom:20px;border-bottom:2px solid var(--border);padding-bottom:0}
    .tabs a{padding:10px 20px;text-decoration:none;color:var(--text-muted);font-size:.85rem;font-weight:600;border-bottom:3px solid transparent;margin-bottom:-2px}
    .tabs a.active{color:var(--primary);border-bottom-color:var(--primary)}
    .tabs a:hover{color:var(--primary)}
    .heatmap{border-collapse:collapse;font-size:.75rem}
    .heatmap th,.heatmap td{padding:6px 10px;text-align:center;border:1px solid var(--border)}
    .heatmap .green{background:#d1fae5}.heatmap .amber{background:#fef3c7}.heatmap .red{background:#fee2e2}
    .iframe-wrap{position:relative;width:100%;padding-bottom:65%;height:0;overflow:hidden;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.1)}
    .iframe-wrap iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:none}
    @media(max-width:768px){.cards{grid-template-columns:1fr 1fr}.container{padding:12px}table{font-size:.75rem}th,td{padding:6px 8px}}
    """


def _page(title, body_html, active_tab='dashboard'):
    tabs_user = f"""
    <div class="tabs">
        <a href="{BASE_PATH}/lms/" class="{'active' if active_tab=='dashboard' else ''}">📊 Dashboard</a>
        <a href="{BASE_PATH}/lms/my-courses" class="{'active' if active_tab=='courses' else ''}">📚 Mijn Trainingen</a>
        <a href="{BASE_PATH}/lms/my-certificates" class="{'active' if active_tab=='certs' else ''}">🏆 Certificaten</a>
    </div>"""
    tabs_admin = f"""
    <div class="tabs">
        <a href="{BASE_PATH}/lms/admin/courses" class="{'active' if active_tab=='admin-courses' else ''}">📖 Cursussen</a>
        <a href="{BASE_PATH}/lms/admin/enrollments" class="{'active' if active_tab=='admin-enroll' else ''}">👥 Inschrijvingen</a>
        <a href="{BASE_PATH}/lms/admin/compliance" class="{'active' if active_tab=='admin-compliance' else ''}">🛡️ Compliance</a>
        <a href="{BASE_PATH}/lms/admin/analytics" class="{'active' if active_tab=='admin-analytics' else ''}">📈 Analytics</a>
    </div>"""
    tabs = tabs_admin if active_tab.startswith('admin') else tabs_user
    return render_template_string(f"""
    <!DOCTYPE html><html lang="nl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{title} — JvG LMS Academy</title>
    <style>{_base_css()}</style></head><body>
    <div class="container">
        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
            <h1>🎓 LMS Academy</h1>
            <div>
                <a href="{BASE_PATH}/lms/" class="btn btn-sm btn-primary">🏠 User Portal</a>
                <a href="{BASE_PATH}/lms/admin/courses" class="btn btn-sm btn-warning">⚙️ Admin</a>
            </div>
        </div>
        {tabs}
        {body_html}
    </div></body></html>""")


# ═══════════════════════════════════════════════════════════════════════════════
# USER PORTAL
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/')
def user_dashboard():
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        enrollments = conn.execute("""
            SELECT e.*, m.title, m.duration_minutes, m.category
            FROM lms_enrollments e
            JOIN elearning_modules m ON m.id = e.elearning_module_id
            WHERE e.employee_id = ?
            ORDER BY e.due_date ASC
        """, (emp_id,)).fetchall()

        completed = sum(1 for e in enrollments if e['status'] == 'completed')
        in_progress = sum(1 for e in enrollments if e['status'] == 'in_progress')
        not_started = sum(1 for e in enrollments if e['status'] == 'not_started')
        expiring = sum(1 for e in enrollments if e['due_date'] and e['due_date'] < str(date.today() + timedelta(days=30)) and e['status'] != 'completed')

        certs = conn.execute("""
            SELECT c.*, m.title
            FROM trn_certificates c
            JOIN elearning_modules m ON m.id = c.module_id
            WHERE c.employee_id = ?
            ORDER BY c.id DESC
        """, (emp_id,)).fetchall()
    finally:
        conn.close()

    rows = ""
    for e in enrollments:
        badge = {'not_started':'badge-muted','in_progress':'badge-info','completed':'badge-success','failed':'badge-danger','expired':'badge-warning'}.get(e['status'],'badge-muted')
        status_label = e['status'].replace('_',' ').title()
        pct = e['progress_percent'] or 0
        rows += f"""<tr>
            <td><strong>{e['title']}</strong><br><small style="color:var(--text-muted)">{e['category'] or ''}</small></td>
            <td><div class="progress-bar"><div class="progress-fill" style="width:{pct}%"></div></div><small>{pct}%</small></td>
            <td><span class="badge {badge}">{status_label}</span></td>
            <td>{e['due_date'] or '—'}</td>
            <td><a href="{BASE_PATH}/lms/course/{e['elearning_module_id']}" class="btn btn-sm btn-primary">Openen</a></td>
        </tr>"""

    body = f"""
    <div class="cards">
        <div class="card"><div class="label">Totaal Trainingen</div><div class="value">{len(enrollments)}</div></div>
        <div class="card success"><div class="label">Voltooid</div><div class="value">{completed}</div></div>
        <div class="card warning"><div class="label">In Uitvoering</div><div class="value">{in_progress}</div></div>
        <div class="card danger"><div class="label">Nakomend / Verlopen</div><div class="value">{expiring}</div></div>
    </div>
    <h2>Mijn Trainingen</h2>
    <table><tr><th>Cursus</th><th>Voortgang</th><th>Status</th><th>Deadline</th><th>Actie</th></tr>
    {rows or '<tr><td colspan="5" style="text-align:center;color:var(--text-muted)">Geen trainingen toegewezen</td></tr>'}
    </table>
    <h2>Recente Certificaten</h2>
    <table><tr><th>Certificaat</th><th>Score</th><th>Datum</th><th>Ref</th></tr>
    {"".join(f'<tr><td>{c["title"]}</td><td>{c["quiz_score"]}%</td><td>{c["passed"]}</td><td>{c["certificate_ref"]}</td></tr>' for c in certs) or '<tr><td colspan="4" style="text-align:center;color:var(--text-muted)">Nog geen certificaten</td></tr>'}
    </table>"""
    return _page('Dashboard', body, 'dashboard')


@lms_bp.route('/my-courses')
def my_courses():
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        enrollments = conn.execute("""
            SELECT e.*, m.title, m.duration_minutes, m.category, m.status as module_status
            FROM lms_enrollments e
            JOIN elearning_modules m ON m.id = e.elearning_module_id
            WHERE e.employee_id = ?
            ORDER BY e.status, e.due_date
        """, (emp_id,)).fetchall()
    finally:
        conn.close()

    rows = ""
    for e in enrollments:
        badge = {'not_started':'badge-muted','in_progress':'badge-info','completed':'badge-success','failed':'badge-danger','expired':'badge-warning'}.get(e['status'],'badge-muted')
        pct = e['progress_percent'] or 0
        rows += f"""<tr>
            <td><strong>{e['title']}</strong></td>
            <td>{e['category'] or '—'}</td>
            <td><div class="progress-bar"><div class="progress-fill" style="width:{pct}%"></div></div><small>{pct}%</small></td>
            <td><span class="badge {badge}">{e['status'].replace('_',' ').title()}</span></td>
            <td>{e['due_date'] or '—'}</td>
            <td><a href="{BASE_PATH}/lms/course/{e['elearning_module_id']}" class="btn btn-sm btn-primary">Openen</a></td>
        </tr>"""

    body = f"""<h2>Alle Toegewezen Trainingen</h2>
    <table><tr><th>Cursus</th><th>Categorie</th><th>Voortgang</th><th>Status</th><th>Deadline</th><th>Actie</th></tr>
    {rows or '<tr><td colspan="6" style="text-align:center;color:var(--text-muted)">Geen trainingen</td></tr>'}
    </table>"""
    return _page('Mijn Trainingen', body, 'courses')


@lms_bp.route('/my-certificates')
def my_certificates():
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        certs = conn.execute("""
            SELECT c.*, m.title
            FROM trn_certificates c
            JOIN elearning_modules m ON m.id = c.module_id
            WHERE c.employee_id = ?
            ORDER BY c.id DESC
        """, (emp_id,)).fetchall()
    finally:
        conn.close()

    rows = "".join(f"""<tr>
        <td><strong>{c['title']}</strong></td>
        <td>{c['quiz_score']}%</td>
        <td><span class="badge {'badge-success' if c['passed'] else 'badge-danger'}">{'Behaald' if c['passed'] else 'Niet behaald'}</span></td>
        <td>{c['certificate_ref'] or '—'}</td>
    </tr>""" for c in certs)

    body = f"""<h2>Mijn Certificaten</h2>
    <table><tr><th>Training</th><th>Score</th><th>Status</th><th>Referentie</th></tr>
    {rows or '<tr><td colspan="4" style="text-align:center;color:var(--text-muted)">Nog geen certificaten behaald</td></tr>'}
    </table>"""
    return _page('Certificaten', body, 'certs')


# ═══════════════════════════════════════════════════════════════════════════════
# COURSE PLAYER
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/course/<int:module_id>')
def course_player(module_id):
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        module = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
        if not module:
            return _page('Fout', '<p>Cursus niet gevonden.</p>', 'courses')
        content = conn.execute("SELECT * FROM lms_course_content WHERE elearning_module_id=? ORDER BY display_order", (module_id,)).fetchall()
        enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()

        # Auto-create enrollment if missing
        if not enrollment:
            conn.execute("INSERT OR IGNORE INTO lms_enrollments (employee_id, elearning_module_id, status) VALUES (?,?, 'not_started')", (emp_id, module_id))
            conn.commit()
            enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()

        # Mark as in_progress
        if enrollment and enrollment['status'] == 'not_started':
            conn.execute("UPDATE lms_enrollments SET status='in_progress', started_at=datetime('now'), last_accessed_at=datetime('now') WHERE id=?", (enrollment['id'],))
            conn.commit()

        # Update last accessed
        if enrollment:
            conn.execute("UPDATE lms_enrollments SET last_accessed_at=datetime('now') WHERE id=?", (enrollment['id'],))
            conn.commit()
    finally:
        conn.close()

    # Build content tabs
    content_tabs = ""
    iframe_src = ""
    for i, c in enumerate(content):
        active = 'btn-primary' if i == 0 else 'btn-sm'
        fname = c['file_name'] or os.path.basename(c['file_path'])
        content_tabs += f'<a href="#" class="btn {active} content-tab" data-src="{BASE_PATH}/lms/serve-content/{c["id"]}">{fname}</a>\n'
        if i == 0:
            iframe_src = f"{BASE_PATH}/lms/serve-content/{c['id']}"

    # If no linked content, check if module has content_html
    if not content and module['content_html']:
        iframe_src = f"{BASE_PATH}/lms/serve-content-inline/{module_id}"
        content_tabs = '<span class="badge badge-info">Inline content</span>'

    pct = enrollment['progress_percent'] or 0 if enrollment else 0
    quiz_url = f"{BASE_PATH}/lms/course/{module_id}/quiz"
    complete_url = f"{BASE_PATH}/lms/course/{module_id}/complete"

    body = f"""
    <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
        <h2>{module['title']}</h2>
        <span class="badge badge-info">{module['duration_minutes'] or 0} min</span>
    </div>
    <div class="progress-bar" style="margin-bottom:12px"><div class="progress-fill" style="width:{pct}%"></div></div>
    <div style="margin-bottom:12px">{content_tabs}</div>
    <div class="iframe-wrap"><iframe id="courseFrame" src="{iframe_src}"></iframe></div>
    <div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end">
        <a href="{quiz_url}" class="btn btn-warning">📝 Quiz Starten</a>
        <form method="POST" action="{complete_url}" style="display:inline"><button class="btn btn-success" type="submit">✅ Afronden</button></form>
    </div>
    <script>
    document.querySelectorAll('.content-tab').forEach(function(tab){{
        tab.addEventListener('click',function(e){{
            e.preventDefault();
            document.getElementById('courseFrame').src=this.dataset.src;
            document.querySelectorAll('.content-tab').forEach(function(t){{t.classList.remove('btn-primary');t.classList.add('btn-sm')}});
            this.classList.add('btn-primary');
        }});
    }});
    // PostMessage listener for quiz integration (SST §9)
    window.addEventListener('message', function(event) {{
        if (event.data && event.data.type === 'lms_quiz_complete') {{
            fetch('{BASE_PATH}/api/lms/score', {{
                method: 'POST',
                headers: {{'Content-Type': 'application/json'}},
                body: JSON.stringify({{
                    employee_id: {emp_id},
                    module_id: event.data.data.module_id || {module_id},
                    answers: event.data.data.answers || {{}},
                    score: event.data.data.score,
                    total_questions: event.data.data.total_questions,
                    correct_answers: event.data.data.correct_answers,
                    time_spent: event.data.data.time_spent || 0
                }})
            }}).then(function(r){{return r.json()}}).then(function(result){{
                if(result.success){{ location.href='{BASE_PATH}/lms/'; }}
                else{{ alert('Fout bij opslaan quiz-resultaat: '+result.error); }}
            }});
        }}
    }});
    </script>"""
    return _page(module['title'], body, 'courses')


@lms_bp.route('/serve-content/<int:content_id>')
def serve_content(content_id):
    """Serve linked HTML content file."""
    conn = get_db()
    try:
        c = conn.execute("SELECT * FROM lms_course_content WHERE id=?", (content_id,)).fetchone()
    finally:
        conn.close()
    if not c:
        return "<p>Content niet gevonden.</p>", 404
    fpath = c['file_path']
    if os.path.exists(fpath):
        with open(fpath, 'r', encoding='utf-8') as f:
            return f.read()
    return f"<p>Bestand niet gevonden op server: {fpath}</p>", 404


@lms_bp.route('/serve-content-inline/<int:module_id>')
def serve_content_inline(module_id):
    """Serve inline content_html from elearning_modules."""
    conn = get_db()
    try:
        m = conn.execute("SELECT content_html FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
    finally:
        conn.close()
    if m and m['content_html']:
        return m['content_html']
    return "<p>Geen content beschikbaar.</p>", 404


@lms_bp.route('/course/<int:module_id>/start', methods=['POST'])
def course_start(module_id):
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        conn.execute("""UPDATE lms_enrollments SET status='in_progress', started_at=datetime('now'), last_accessed_at=datetime('now')
                        WHERE employee_id=? AND elearning_module_id=?""", (emp_id, module_id))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/course/{module_id}")


@lms_bp.route('/course/<int:module_id>/progress', methods=['POST'])
def course_progress(module_id):
    emp_id = _current_employee_id()
    data = request.get_json(silent=True) or {}
    pct = data.get('progress_percent', 0)
    ts = data.get('time_spent_seconds', 0)
    conn = get_db()
    try:
        conn.execute("""UPDATE lms_enrollments SET progress_percent=?, time_spent_seconds=time_spent_seconds+?, last_accessed_at=datetime('now')
                        WHERE employee_id=? AND elearning_module_id=?""", (pct, ts, emp_id, module_id))
        conn.commit()
    finally:
        conn.close()
    return jsonify(success=True)


@lms_bp.route('/course/<int:module_id>/complete', methods=['POST'])
def course_complete(module_id):
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        conn.execute("""UPDATE lms_enrollments SET progress_percent=100, last_accessed_at=datetime('now')
                        WHERE employee_id=? AND elearning_module_id=? AND status='in_progress'""", (emp_id, module_id))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/course/{module_id}")


# ═══════════════════════════════════════════════════════════════════════════════
# QUIZ ENGINE
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/course/<int:module_id>/quiz')
def quiz_view(module_id):
    emp_id = _current_employee_id()
    conn = get_db()
    try:
        module = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
        enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()
    finally:
        conn.close()

    if not module:
        return _page('Fout', '<p>Module niet gevonden.</p>', 'courses')

    # Try loading quiz questions from module
    questions = []
    if module['quiz_questions']:
        try:
            questions = json.loads(module['quiz_questions'])
        except (json.JSONDecodeError, TypeError):
            pass

    # Check if there's a linked quiz HTML file
    conn = get_db()
    try:
        quiz_content = conn.execute("SELECT * FROM lms_course_content WHERE elearning_module_id=? AND file_name LIKE '%quiz%'", (module_id,)).fetchone()
    finally:
        conn.close()

    if quiz_content and os.path.exists(quiz_content['file_path']):
        # Serve external quiz HTML in iframe
        quiz_src = f"{BASE_PATH}/lms/serve-content/{quiz_content['id']}"
        body = f"""
        <h2>Quiz: {module['title']}</h2>
        <div class="iframe-wrap"><iframe id="quizFrame" src="{quiz_src}" style="width:100%;height:600px;border:none;"></iframe></div>
        <p style="margin-top:12px;color:var(--text-muted);font-size:.85rem">De quiz wordt automatisch nagekeken. Resultaat wordt opgeslagen na afronding.</p>
        <script>
        window.addEventListener('message', function(event) {{
            if (event.data && event.data.type === 'lms_quiz_complete') {{
                fetch('{BASE_PATH}/api/lms/score', {{
                    method: 'POST',
                    headers: {{'Content-Type': 'application/json'}},
                    body: JSON.stringify({{
                        employee_id: {emp_id},
                        module_id: event.data.data.module_id || {module_id},
                        answers: event.data.data.answers || {{}},
                        score: event.data.data.score,
                        total_questions: event.data.data.total_questions,
                        correct_answers: event.data.data.correct_answers,
                        time_spent: event.data.data.time_spent || 0
                    }})
                }}).then(function(r){{return r.json()}}).then(function(result){{
                    if(result.success){{
                        document.getElementById('quizFrame').parentElement.innerHTML='<div class="card" style="text-align:center;padding:40px"><h2>'+result.score+'%</h2><p>'+(result.passed?'✅ Gehaald!':'❌ Niet gehaald')+'</p><a href="{BASE_PATH}/lms/" class="btn btn-primary">Terug naar Dashboard</a></div>';
                    }}
                }});
            }}
        }});
        </script>"""
        return _page(f'Quiz: {module["title"]}', body, 'courses')

    # Built-in quiz rendering from quiz_questions JSON
    if not questions:
        body = f"""<h2>Quiz: {module['title']}</h2>
        <div class="card" style="text-align:center;padding:40px">
            <p>Geen quiz beschikbaar voor deze module.</p>
            <a href="{BASE_PATH}/lms/course/{module_id}" class="btn btn-primary">Terug naar cursus</a>
        </div>"""
        return _page(f'Quiz: {module["title"]}', body, 'courses')

    # Render questions
    q_html = ""
    for i, q in enumerate(questions):
        opts = ""
        for j, opt in enumerate(q.get('options', [])):
            letter = chr(65 + j)
            opts += f'<label style="display:block;padding:8px 12px;margin:4px 0;border-radius:6px;cursor:pointer;border:1px solid var(--border)" class="quiz-opt" data-q="{i}" data-a="{letter}"><input type="radio" name="q{i}" value="{letter}" style="margin-right:8px">{letter}. {opt}</label>'
        q_html += f'<div class="card" style="margin-bottom:16px"><p style="font-weight:600;margin-bottom:12px">{i+1}. {q.get("question","")}</p>{opts}</div>'

    body = f"""
    <h2>Quiz: {module['title']}</h2>
    <form id="quizForm">
        {q_html}
        <div style="text-align:center;margin-top:20px">
            <button type="submit" class="btn btn-success">📋 Inleveren</button>
        </div>
    </form>
    <div id="quizResult" style="display:none"></div>
    <script>
    document.getElementById('quizForm').addEventListener('submit', function(e){{
        e.preventDefault();
        var answers={{}};
        document.querySelectorAll('input[type=radio]:checked').forEach(function(inp){{
            var qIdx=inp.name.replace('q','');
            answers[parseInt(qIdx)+1]=inp.value;
        }});
        fetch('{BASE_PATH}/lms/course/{module_id}/quiz/submit', {{
            method:'POST',
            headers:{{'Content-Type':'application/json'}},
            body:JSON.stringify({{answers:answers}})
        }}).then(function(r){{return r.json()}}).then(function(res){{
            document.getElementById('quizForm').style.display='none';
            var rd=document.getElementById('quizResult');
            rd.style.display='block';
            rd.innerHTML='<div class="card" style="text-align:center;padding:40px"><h2>'+res.score+'%</h2><p>'+res.score+'/'+res.total_questions+' correct</p><p>'+(res.passed?'✅ Gehaald!':'❌ Niet gehaald — minimum '+res.passing_score+'%')+'</p><a href="{BASE_PATH}/lms/" class="btn btn-primary">Terug naar Dashboard</a></div>';
        }});
    }});
    </script>"""
    return _page(f'Quiz: {module["title"]}', body, 'courses')


@lms_bp.route('/course/<int:module_id>/quiz/submit', methods=['POST'])
def quiz_submit(module_id):
    """Internal quiz submission — scores against quiz_questions JSON."""
    emp_id = _current_employee_id()
    data = request.get_json(silent=True) or {}
    answers = data.get('answers', {})

    conn = get_db()
    try:
        module = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
        if not module:
            return jsonify(success=False, error="Module niet gevonden"), 404

        questions = []
        if module['quiz_questions']:
            try:
                questions = json.loads(module['quiz_questions'])
            except (json.JSONDecodeError, TypeError):
                pass

        correct = 0
        total = len(questions)
        for i, q in enumerate(questions):
            user_ans = answers.get(str(i + 1), '')
            if user_ans.upper() == q.get('correct', '').upper():
                correct += 1

        score = int((correct / total) * 100) if total > 0 else 0
        passing_score = module['passing_score'] or 70
        passed = 1 if score >= passing_score else 0

        # Get or create enrollment
        enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()
        if not enrollment:
            conn.execute("INSERT OR IGNORE INTO lms_enrollments (employee_id, elearning_module_id, status) VALUES (?,?, 'in_progress')", (emp_id, module_id))
            conn.commit()
            enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()

        # Determine attempt number
        attempt = conn.execute("SELECT MAX(attempt_number) as m FROM lms_quiz_results WHERE enrollment_id=?", (enrollment['id'],)).fetchone()
        attempt_num = (attempt['m'] or 0) + 1

        # Insert quiz result
        conn.execute("""INSERT INTO lms_quiz_results (enrollment_id, attempt_number, answers_json, total_questions, correct_answers, score, passed, submitted_at)
                        VALUES (?,?,?,?,?,?,?,datetime('now'))""",
                     (enrollment['id'], attempt_num, json.dumps(answers), total, correct, score, passed))

        # Update enrollment
        new_status = 'completed' if passed else 'failed'
        conn.execute("""UPDATE lms_enrollments SET progress_percent=100, final_score=?, final_passed=?, completed_at=datetime('now'), status=?, last_accessed_at=datetime('now')
                        WHERE id=?""", (score, passed, new_status, enrollment['id']))

        # Generate certificate if passed
        cert_ref = None
        if passed:
            cert_ref = f"JvG-LMS-{module_id:03d}-{emp_id:04d}-{uuid.uuid4().hex[:6].upper()}"
            conn.execute("""INSERT INTO trn_certificates (employee_id, module_id, quiz_score, passed, certificate_ref)
                            VALUES (?,?,?,?,?)""", (emp_id, module_id, score, 1, cert_ref))

            # Update certifications table if training_program linked
            compliance_rule = conn.execute("SELECT training_program_id FROM lms_compliance_rules WHERE elearning_module_id=?", (module_id,)).fetchone()
            if compliance_rule and compliance_rule['training_program_id']:
                tp_id = compliance_rule['training_program_id']
                # Get valid_period from training_programs
                tp = conn.execute("SELECT valid_period_days FROM training_programs WHERE id=?", (tp_id,)).fetchone()
                vdays = tp['valid_period_days'] if tp else 365
                expiry = str(date.today() + timedelta(days=vdays))
                existing = conn.execute("SELECT id FROM certifications WHERE employee_id=? AND training_program_id=?", (emp_id, tp_id)).fetchone()
                if existing:
                    conn.execute("UPDATE certifications SET expiry_date=?, status='active', score=?, updated_at=datetime('now') WHERE id=?",
                                 (expiry, score, existing['id']))
                else:
                    conn.execute("INSERT INTO certifications (employee_id, training_program_id, expiry_date, status, score) VALUES (?,?,?,?,?)",
                                 (emp_id, tp_id, expiry, 'active', score))

        conn.commit()
    finally:
        conn.close()

    return jsonify(success=True, score=score, total_questions=total, correct_answers=correct,
                   passed=bool(passed), passing_score=passing_score, certificate_ref=cert_ref)


# ═══════════════════════════════════════════════════════════════════════════════
# EXTERNAL SCORE API (for existing HTML quiz files)
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/api/lms/score', methods=['POST'])
def api_score():
    """External score endpoint — called by existing HTML quiz files via fetch/XHR."""
    data = request.get_json(silent=True) or {}
    emp_id = data.get('employee_id', _current_employee_id())
    module_id = data.get('module_id')
    score = data.get('score', 0)
    total_q = data.get('total_questions', 0)
    correct = data.get('correct_answers', 0)
    answers = data.get('answers', {})
    time_spent = data.get('time_spent', 0)

    if not module_id:
        return jsonify(success=False, error="module_id verplicht"), 400

    conn = get_db()
    try:
        module = conn.execute("SELECT id, passing_score FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
        if not module:
            return jsonify(success=False, error="Module niet gevonden"), 404

        passing_score = module['passing_score'] or 70
        passed = 1 if score >= passing_score else 0

        # Get or create enrollment
        conn.execute("INSERT OR IGNORE INTO lms_enrollments (employee_id, elearning_module_id, status) VALUES (?,?, 'in_progress')", (emp_id, module_id))
        conn.commit()
        enrollment = conn.execute("SELECT * FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=?", (emp_id, module_id)).fetchone()

        # Attempt number
        attempt = conn.execute("SELECT MAX(attempt_number) as m FROM lms_quiz_results WHERE enrollment_id=?", (enrollment['id'],)).fetchone()
        attempt_num = (attempt['m'] or 0) + 1

        # Insert quiz result
        conn.execute("""INSERT INTO lms_quiz_results (enrollment_id, attempt_number, answers_json, total_questions, correct_answers, score, passed, time_spent_seconds, submitted_at)
                        VALUES (?,?,?,?,?,?,?,?,datetime('now'))""",
                     (enrollment['id'], attempt_num, json.dumps(answers), total_q, correct, score, passed, time_spent))

        # Update enrollment
        new_status = 'completed' if passed else 'failed'
        conn.execute("""UPDATE lms_enrollments SET progress_percent=100, final_score=?, final_passed=?, completed_at=datetime('now'), status=?, time_spent_seconds=time_spent_seconds+?, last_accessed_at=datetime('now')
                        WHERE id=?""", (score, passed, new_status, time_spent, enrollment['id']))

        # Certificate
        cert_ref = None
        if passed:
            cert_ref = f"JvG-LMS-{module_id:03d}-{emp_id:04d}-{uuid.uuid4().hex[:6].upper()}"
            conn.execute("""INSERT INTO trn_certificates (employee_id, module_id, quiz_score, passed, certificate_ref)
                            VALUES (?,?,?,?,?)""", (emp_id, module_id, score, 1, cert_ref))

            # Compliance link
            cr = conn.execute("SELECT training_program_id FROM lms_compliance_rules WHERE elearning_module_id=?", (module_id,)).fetchone()
            if cr and cr['training_program_id']:
                tp_id = cr['training_program_id']
                tp = conn.execute("SELECT valid_period_days FROM training_programs WHERE id=?", (tp_id,)).fetchone()
                vdays = tp['valid_period_days'] if tp else 365
                expiry = str(date.today() + timedelta(days=vdays))
                existing = conn.execute("SELECT id FROM certifications WHERE employee_id=? AND training_program_id=?", (emp_id, tp_id)).fetchone()
                if existing:
                    conn.execute("UPDATE certifications SET expiry_date=?, status='active', score=? WHERE id=?", (expiry, score, existing['id']))
                else:
                    conn.execute("INSERT INTO certifications (employee_id, training_program_id, expiry_date, status, score) VALUES (?,?,?,?,?)",
                                 (emp_id, tp_id, expiry, 'active', score))

        conn.commit()
    finally:
        conn.close()

    return jsonify(success=True, score=score, passed=bool(passed), certificate_ref=cert_ref)


# ═══════════════════════════════════════════════════════════════════════════════
# JSON API ENDPOINTS
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/api/lms/modules')
def api_modules():
    conn = get_db()
    try:
        rows = conn.execute("SELECT * FROM elearning_modules WHERE status='published' ORDER BY id").fetchall()
    finally:
        conn.close()
    return jsonify([dict(r) for r in rows])


@lms_bp.route('/api/lms/modules/<int:module_id>')
def api_module_detail(module_id):
    conn = get_db()
    try:
        m = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (module_id,)).fetchone()
        if not m:
            return jsonify(error="Not found"), 404
        content = conn.execute("SELECT * FROM lms_course_content WHERE elearning_module_id=?", (module_id,)).fetchall()
    finally:
        conn.close()
    result = dict(m)
    result['content_files'] = [dict(c) for c in content]
    return jsonify(result)


@lms_bp.route('/api/lms/enrollments/<int:employee_id>')
def api_enrollments(employee_id):
    conn = get_db()
    try:
        rows = conn.execute("""
            SELECT e.*, m.title, m.category
            FROM lms_enrollments e
            JOIN elearning_modules m ON m.id = e.elearning_module_id
            WHERE e.employee_id=?
            ORDER BY e.status
        """, (employee_id,)).fetchall()
    finally:
        conn.close()
    return jsonify([dict(r) for r in rows])


@lms_bp.route('/api/lms/compliance/summary')
def api_compliance_summary():
    conn = get_db()
    try:
        employees = conn.execute("SELECT id, first_name, last_name, role_id FROM employees WHERE status='active'").fetchall()
        total = len(employees)
        compliant = 0
        for emp in employees:
            rules = conn.execute("""
                SELECT cr.elearning_module_id, cr.valid_period_days, cr.is_mandatory
                FROM lms_compliance_rules cr WHERE cr.is_mandatory=1
            """).fetchall()
            if not rules:
                compliant += 1
                continue
            all_ok = True
            for rule in rules:
                enr = conn.execute("""SELECT final_passed, completed_at FROM lms_enrollments
                                      WHERE employee_id=? AND elearning_module_id=? ORDER BY completed_at DESC LIMIT 1""",
                                   (emp['id'], rule['elearning_module_id'])).fetchone()
                if not enr or not enr['final_passed']:
                    all_ok = False
                    break
                expiry = datetime.strptime(enr['completed_at'], '%Y-%m-%d %H:%M:%S') + timedelta(days=rule['valid_period_days'])
                if expiry.date() < date.today():
                    all_ok = False
                    break
            if all_ok:
                compliant += 1
    finally:
        conn.close()
    pct = int((compliant / total) * 100) if total > 0 else 0
    return jsonify(total_employees=total, compliant=compliant, non_compliant=total - compliant, compliance_pct=pct)


@lms_bp.route('/api/lms/certificates/<int:employee_id>')
def api_certificates(employee_id):
    conn = get_db()
    try:
        rows = conn.execute("""
            SELECT c.*, m.title FROM trn_certificates c
            JOIN elearning_modules m ON m.id = c.module_id
            WHERE c.employee_id=?
        """, (employee_id,)).fetchall()
    finally:
        conn.close()
    return jsonify([dict(r) for r in rows])


# ═══════════════════════════════════════════════════════════════════════════════
# ADMIN PORTAL — COURSES
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/admin/courses')
def admin_courses():
    conn = get_db()
    try:
        modules = conn.execute("""
            SELECT m.*, 
                (SELECT COUNT(*) FROM lms_enrollments WHERE elearning_module_id=m.id) as enroll_count,
                (SELECT ROUND(AVG(final_score)) FROM lms_enrollments WHERE elearning_module_id=m.id AND final_score IS NOT NULL) as avg_score
            FROM elearning_modules m ORDER BY m.id
        """).fetchall()
    finally:
        conn.close()

    rows = ""
    for m in modules:
        badge = {'published':'badge-success','draft':'badge-muted','archived':'badge-warning'}.get(m['status'], 'badge-muted')
        rows += f"""<tr>
            <td>{m['id']}</td>
            <td><strong>{m['title']}</strong></td>
            <td>{m['category'] or '—'}</td>
            <td><span class="badge {badge}">{m['status']}</span></td>
            <td>{m['enroll_count']}</td>
            <td>{m['avg_score'] or '—'}%</td>
            <td>{m['passing_score'] or 70}%</td>
            <td>
                <a href="{BASE_PATH}/lms/admin/courses/{m['id']}/content" class="btn btn-sm btn-primary">📎 Content</a>
                <form method="POST" action="{BASE_PATH}/lms/admin/courses/{m['id']}/publish" style="display:inline"><button class="btn btn-sm btn-success" type="submit">📢 Publiceren</button></form>
            </td>
        </tr>"""

    body = f"""
    <h2>Cursusbeheer</h2>
    <table><tr><th>ID</th><th>Titel</th><th>Categorie</th><th>Status</th><th>Inschrijvingen</th><th>Gem. Score</th><th>Slagings%</th><th>Acties</th></tr>
    {rows or '<tr><td colspan="8" style="text-align:center;color:var(--text-muted)">Geen cursussen</td></tr>'}
    </table>"""
    return _page('Cursusbeheer', body, 'admin-courses')


@lms_bp.route('/admin/courses/<int:course_id>/content')
def admin_course_content(course_id):
    conn = get_db()
    try:
        module = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (course_id,)).fetchone()
        content = conn.execute("SELECT * FROM lms_course_content WHERE elearning_module_id=? ORDER BY display_order", (course_id,)).fetchall()
    finally:
        conn.close()

    rows = ""
    for c in content:
        rows += f"""<tr>
            <td>{c['id']}</td>
            <td>{c['content_type']}</td>
            <td>{c['file_name'] or '—'}</td>
            <td><small>{c['file_path']}</small></td>
            <td>{'✅' if c['is_primary'] else '—'}</td>
        </tr>"""

    body = f"""
    <h2>Content: {module['title'] if module else 'Onbekend'}</h2>
    <form method="POST" action="{BASE_PATH}/lms/admin/courses/{course_id}/content" style="margin-bottom:16px">
        <div style="display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:8px;align-items:end">
            <div><label style="font-size:.75rem;color:var(--text-muted)">Content Type</label><select name="content_type" class="form-control" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px"><option value="html">HTML</option><option value="pdf">PDF</option><option value="video">Video</option></select></div>
            <div><label style="font-size:.75rem;color:var(--text-muted)">Bestandspad (server)</label><input type="text" name="file_path" placeholder="/pad/naar/bestand.html" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px"></div>
            <div><label style="font-size:.75rem;color:var(--text-muted)">Bestandsnaam</label><input type="text" name="file_name" placeholder="naam.html" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px"></div>
            <button class="btn btn-primary" type="submit">Toevoegen</button>
        </div>
    </form>
    <table><tr><th>ID</th><th>Type</th><th>Bestand</th><th>Pad</th><th>Primair</th></tr>
    {rows or '<tr><td colspan="5" style="text-align:center;color:var(--text-muted)">Geen content gekoppeld</td></tr>'}
    </table>"""
    return _page(f'Content: {module["title"] if module else "?"}', body, 'admin-courses')


@lms_bp.route('/admin/courses/<int:course_id>/content', methods=['POST'])
def admin_course_content_add(course_id):
    data = request.form
    fpath = data.get('file_path', '')
    fname = data.get('file_name', '') or os.path.basename(fpath)
    ctype = data.get('content_type', 'html')
    conn = get_db()
    try:
        conn.execute("""INSERT INTO lms_course_content (elearning_module_id, content_type, file_path, file_name, is_primary)
                        VALUES (?,?,?,?, (SELECT CASE WHEN (SELECT COUNT(*) FROM lms_course_content WHERE elearning_module_id=? AND is_primary=1)=0 THEN 1 ELSE 0 END))""",
                     (course_id, ctype, fpath, fname, course_id))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/admin/courses/{course_id}/content")


@lms_bp.route('/admin/courses/<int:course_id>/publish', methods=['POST'])
def admin_course_publish(course_id):
    conn = get_db()
    try:
        conn.execute("UPDATE elearning_modules SET status='published' WHERE id=?", (course_id,))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/admin/courses")


# ═══════════════════════════════════════════════════════════════════════════════
# ADMIN PORTAL — ENROLLMENTS
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/admin/enrollments')
def admin_enrollments():
    conn = get_db()
    try:
        enrollments = conn.execute("""
            SELECT e.*, em.first_name, em.last_name, em.employee_number, m.title as module_title
            FROM lms_enrollments e
            JOIN employees em ON em.id = e.employee_id
            JOIN elearning_modules m ON m.id = e.elearning_module_id
            ORDER BY e.status, e.due_date
        """).fetchall()
        modules = conn.execute("SELECT id, title FROM elearning_modules ORDER BY id").fetchall()
        employees = conn.execute("SELECT id, first_name, last_name FROM employees WHERE status='active' ORDER BY id").fetchall()
        roles = conn.execute("SELECT id, role_name FROM roles ORDER BY id").fetchall()
    finally:
        conn.close()

    rows = ""
    for e in enrollments:
        badge = {'not_started':'badge-muted','in_progress':'badge-info','completed':'badge-success','failed':'badge-danger','expired':'badge-warning','withdrawn':'badge-muted'}.get(e['status'],'badge-muted')
        rows += f"""<tr>
            <td>{e['employee_number'] or e['employee_id']}</td>
            <td>{e['first_name']} {e['last_name']}</td>
            <td>{e['module_title']}</td>
            <td><span class="badge {badge}">{e['status'].replace('_',' ').title()}</span></td>
            <td>{e['final_score'] or '—'}</td>
            <td>{e['due_date'] or '—'}</td>
            <td>
                <form method="POST" action="{BASE_PATH}/lms/admin/enrollments/{e['id']}" style="display:inline"><input type="hidden" name="_method" value="DELETE"><button class="btn btn-sm btn-danger" type="submit">🗑️</button></form>
            </td>
        </tr>"""

    emp_opts = "".join(f'<option value="{e["id"]}">{e["first_name"]} {e["last_name"]}</option>' for e in employees)
    mod_opts = "".join(f'<option value="{m["id"]}">{m["title"]}</option>' for m in modules)
    role_opts = "".join(f'<option value="{r["id"]}">{r["role_name"]}</option>' for r in roles)

    body = f"""
    <h2>Inschrijvingen</h2>
    <div class="card" style="margin-bottom:20px;padding:16px">
        <h2 style="margin-top:0">Training Toewijzen</h2>
        <form method="POST" action="{BASE_PATH}/lms/admin/enrollments">
            <div style="display:grid;grid-template-columns:1fr 1fr auto;gap:8px;align-items:end">
                <div><label style="font-size:.75rem;color:var(--text-muted)">Medewerker(s)</label><select name="employee_id" multiple style="width:100%;height:80px;padding:8px;border:1px solid var(--border);border-radius:6px">{emp_opts}</select><small>Ctrl+klik voor meerdere</small></div>
                <div><label style="font-size:.75rem;color:var(--text-muted)">Cursus</label><select name="module_id" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px">{mod_opts}</select></div>
                <button class="btn btn-success" type="submit">Toewijzen</button>
            </div>
        </form>
        <form method="POST" action="{BASE_PATH}/lms/admin/enrollments/bulk" style="margin-top:12px">
            <div style="display:grid;grid-template-columns:1fr 1fr auto;gap:8px;align-items:end">
                <div><label style="font-size:.75rem;color:var(--text-muted)">Functie (bulk)</label><select name="role_id" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px">{role_opts}</select></div>
                <div><label style="font-size:.75rem;color:var(--text-muted)">Cursus</label><select name="module_id" style="width:100%;padding:8px;border:1px solid var(--border);border-radius:6px">{mod_opts}</select></div>
                <button class="btn btn-warning" type="submit">Bulk Toewijzen</button>
            </div>
        </form>
    </div>
    <table><tr><th>Medew.</th><th>Naam</th><th>Cursus</th><th>Status</th><th>Score</th><th>Deadline</th><th>Actie</th></tr>
    {rows or '<tr><td colspan="7" style="text-align:center;color:var(--text-muted)">Geen inschrijvingen</td></tr>'}
    </table>"""
    return _page('Inschrijvingen', body, 'admin-enroll')


@lms_bp.route('/admin/enrollments', methods=['POST'])
def admin_enrollment_create():
    data = request.form
    module_id = data.get('module_id', type=int)
    emp_id = data.getlist('employee_id')
    if not module_id or not emp_id:
        return redirect(f"{BASE_PATH}/lms/admin/enrollments")
    conn = get_db()
    try:
        for eid in emp_id:
            conn.execute("INSERT OR IGNORE INTO lms_enrollments (employee_id, elearning_module_id, status, due_date) VALUES (?,?, 'not_started', date('now','+30 days'))",
                         (int(eid), module_id))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/admin/enrollments")


@lms_bp.route('/admin/enrollments/bulk', methods=['POST'])
def admin_enrollment_bulk():
    data = request.form
    module_id = data.get('module_id', type=int)
    role_id = data.get('role_id', type=int)
    if not module_id or not role_id:
        return redirect(f"{BASE_PATH}/lms/admin/enrollments")
    conn = get_db()
    try:
        emps = conn.execute("SELECT id FROM employees WHERE role_id=? AND status='active'", (role_id,)).fetchall()
        for e in emps:
            conn.execute("INSERT OR IGNORE INTO lms_enrollments (employee_id, elearning_module_id, status, due_date) VALUES (?,?, 'not_started', date('now','+30 days'))",
                         (e['id'], module_id))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/admin/enrollments")


@lms_bp.route('/admin/enrollments/<int:enrollment_id>', methods=['POST'])
def admin_enrollment_delete(enrollment_id):
    conn = get_db()
    try:
        conn.execute("DELETE FROM lms_quiz_results WHERE enrollment_id=?", (enrollment_id,))
        conn.execute("DELETE FROM lms_enrollments WHERE id=?", (enrollment_id,))
        conn.commit()
    finally:
        conn.close()
    return redirect(f"{BASE_PATH}/lms/admin/enrollments")


# ═══════════════════════════════════════════════════════════════════════════════
# ADMIN PORTAL — COMPLIANCE
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/admin/compliance')
def admin_compliance():
    conn = get_db()
    try:
        employees = conn.execute("SELECT e.id, e.first_name, e.last_name, e.role_id, r.role_name FROM employees e LEFT JOIN roles r ON r.id=e.role_id WHERE e.status='active' ORDER BY e.id").fetchall()
        modules = conn.execute("SELECT id, title FROM elearning_modules WHERE status='published' ORDER BY id").fetchall()
        rules = conn.execute("SELECT * FROM lms_compliance_rules").fetchall()
        rules_map = {r['elearning_module_id']: r for r in rules}
    finally:
        conn.close()

    # Build heatmap matrix: role × module
    role_modules = {}
    for m in modules:
        for e in employees:
            rid = e['role_id'] or 0
            if rid not in role_modules:
                role_modules[rid] = {'role_name': e['role_name'] or f'Rol {rid}', 'cells': {}}

    # Calculate compliance per employee
    conn = get_db()
    try:
        emp_status = {}
        for e in employees:
            emp_status[e['id']] = {}
            for m in modules:
                rule = rules_map.get(m['id'])
                is_mandatory = rule and rule['is_mandatory']
                enr = conn.execute("SELECT final_passed, completed_at FROM lms_enrollments WHERE employee_id=? AND elearning_module_id=? ORDER BY completed_at DESC LIMIT 1",
                                   (e['id'], m['id'])).fetchone()
                if not is_mandatory:
                    status = 'na'
                elif not enr or not enr['final_passed']:
                    status = 'red'
                elif enr['completed_at']:
                    vdays = rule['valid_period_days'] if rule else 365
                    try:
                        comp_date = datetime.strptime(enr['completed_at'], '%Y-%m-%d %H:%M:%S')
                    except ValueError:
                        comp_date = datetime.strptime(enr['completed_at'][:10], '%Y-%m-%d')
                    expiry = comp_date + timedelta(days=vdays)
                    if expiry.date() < date.today():
                        status = 'red'
                    elif expiry.date() < date.today() + timedelta(days=30):
                        status = 'amber'
                    else:
                        status = 'green'
                else:
                    status = 'red'
                emp_status[e['id']][m['id']] = status
    finally:
        conn.close()

    # Compliance summary cards
    total_mandatory = 0
    compliant_count = 0
    for e in employees:
        for m in modules:
            rule = rules_map.get(m['id'])
            if rule and rule['is_mandatory']:
                total_mandatory += 1
                if emp_status[e['id']][m['id']] == 'green':
                    compliant_count += 1
    pct = int((compliant_count / total_mandatory) * 100) if total_mandatory > 0 else 100

    # Build employee detail table
    emp_rows = ""
    for e in employees:
        cells = ""
        for m in modules:
            s = emp_status[e['id']].get(m['id'], 'na')
            color = {'green':'green','amber':'amber','red':'red','na':''}.get(s, '')
            label = {'green':'✅','amber':'⚠️','red':'❌','na':'—'}.get(s, '—')
            cells += f'<td class="{color}">{label}</td>'
        emp_rows += f'<tr><td>{e["first_name"]} {e["last_name"]}</td><td>{e["role_name"] or "—"}</td>{cells}</tr>'

    mod_headers = "".join(f'<th style="font-size:.65rem;max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="{m["title"]}">{m["title"][:20]}</th>' for m in modules)

    body = f"""
    <div class="cards">
        <div class="card"><div class="label">Compliance</div><div class="value">{pct}%</div></div>
        <div class="card {'success' if pct >= 80 else 'danger'}"><div class="label">Verplichte Trainingen</div><div class="value">{compliant_count}/{total_mandatory}</div></div>
    </div>
    <h2>Compliance Matrix (Medewerker × Training)</h2>
    <div style="overflow-x:auto">
    <table class="heatmap"><tr><th>Medewerker</th><th>Functie</th>{mod_headers}</tr>
    {emp_rows}
    </table>
    </div>
    <p style="margin-top:12px;font-size:.75rem;color:var(--text-muted)">✅ Actief &nbsp; ⚠️ Vervalt binnen 30 dagen &nbsp; ❌ Verlopen/Ontbreekt &nbsp; — Niet verplicht</p>"""
    return _page('Compliance', body, 'admin-compliance')


@lms_bp.route('/admin/compliance/matrix')
def admin_compliance_matrix():
    return redirect(f"{BASE_PATH}/lms/admin/compliance")


@lms_bp.route('/admin/compliance/expired')
def admin_compliance_expired():
    conn = get_db()
    try:
        expired = conn.execute("""
            SELECT e.first_name, e.last_name, e.employee_number, m.title,
                   enr.completed_at, cr.valid_period_days,
                   date(enr.completed_at, '+' || cr.valid_period_days || ' days') as expiry_date
            FROM lms_enrollments enr
            JOIN employees e ON e.id=enr.employee_id
            JOIN elearning_modules m ON m.id=enr.elearning_module_id
            LEFT JOIN lms_compliance_rules cr ON cr.elearning_module_id=enr.elearning_module_id
            WHERE enr.final_passed=1 AND cr.is_mandatory=1
            AND date(enr.completed_at, '+' || cr.valid_period_days || ' days') < date('now')
            ORDER BY expiry_date
        """).fetchall()
    finally:
        conn.close()

    rows = "".join(f"""<tr>
        <td>{e['employee_number'] or ''}</td>
        <td>{e['first_name']} {e['last_name']}</td>
        <td>{e['title']}</td>
        <td><span class="badge badge-danger">Verlopen</span></td>
        <td>{e['expiry_date']}</td>
    </tr>""" for e in expired)

    body = f"""<h2>Verlopen Trainingen</h2>
    <table><tr><th>Nr</th><th>Naam</th><th>Training</th><th>Status</th><th>Vervaldatum</th></tr>
    {rows or '<tr><td colspan="5" style="text-align:center;color:var(--text-muted)">Geen verlopen trainingen</td></tr>'}
    </table>"""
    return _page('Verlopen Trainingen', body, 'admin-compliance')


@lms_bp.route('/admin/compliance/alerts')
def admin_compliance_alerts():
    conn = get_db()
    try:
        alerts = conn.execute("""
            SELECT e.first_name, e.last_name, e.employee_number, m.title,
                   enr.completed_at, cr.valid_period_days,
                   date(enr.completed_at, '+' || cr.valid_period_days || ' days') as expiry_date
            FROM lms_enrollments enr
            JOIN employees e ON e.id=enr.employee_id
            JOIN elearning_modules m ON m.id=enr.elearning_module_id
            LEFT JOIN lms_compliance_rules cr ON cr.elearning_module_id=enr.elearning_module_id
            WHERE enr.final_passed=1 AND cr.is_mandatory=1
            AND date(enr.completed_at, '+' || cr.valid_period_days || ' days') BETWEEN date('now') AND date('now','+30 days')
            ORDER BY expiry_date
        """).fetchall()
    finally:
        conn.close()

    rows = "".join(f"""<tr>
        <td>{a['employee_number'] or ''}</td>
        <td>{a['first_name']} {a['last_name']}</td>
        <td>{a['title']}</td>
        <td><span class="badge badge-warning">Vervalt binnen 30 dagen</span></td>
        <td>{a['expiry_date']}</td>
    </tr>""" for a in alerts)

    body = f"""<h2>Compliance Alerts — Nakomend</h2>
    <table><tr><th>Nr</th><th>Naam</th><th>Training</th><th>Status</th><th>Vervaldatum</th></tr>
    {rows or '<tr><td colspan="5" style="text-align:center;color:var(--text-muted)">Geen nakomende vervallen</td></tr>'}
    </table>"""
    return _page('Compliance Alerts', body, 'admin-compliance')


@lms_bp.route('/admin/compliance/rules', methods=['POST'])
def admin_compliance_rules():
    data = request.get_json(silent=True) or request.form
    module_id = data.get('elearning_module_id', type=int) or int(data.get('elearning_module_id', 0))
    tp_id = data.get('training_program_id', type=int) or int(data.get('training_program_id', 0)) or None
    is_mandatory = data.get('is_mandatory', 0)
    auto_assign = data.get('auto_assign', 0)
    valid_days = data.get('valid_period_days', 365)

    if not module_id:
        return jsonify(success=False, error="module_id verplicht"), 400

    conn = get_db()
    try:
        conn.execute("""INSERT INTO lms_compliance_rules (elearning_module_id, training_program_id, is_mandatory, auto_assign, valid_period_days, updated_at)
                        VALUES (?,?,?,?,?,datetime('now'))""",
                     (module_id, tp_id, is_mandatory, auto_assign, valid_days))
        conn.commit()
    finally:
        conn.close()
    return jsonify(success=True)


# ═══════════════════════════════════════════════════════════════════════════════
# ADMIN PORTAL — ANALYTICS
# ═══════════════════════════════════════════════════════════════════════════════

@lms_bp.route('/admin/analytics')
def admin_analytics():
    conn = get_db()
    try:
        total_enroll = conn.execute("SELECT COUNT(*) as c FROM lms_enrollments").fetchone()['c']
        completed = conn.execute("SELECT COUNT(*) as c FROM lms_enrollments WHERE status='completed'").fetchone()['c']
        failed = conn.execute("SELECT COUNT(*) as c FROM lms_enrollments WHERE status='failed'").fetchone()['c']
        in_progress = conn.execute("SELECT COUNT(*) as c FROM lms_enrollments WHERE status='in_progress'").fetchone()['c']
        avg_score = conn.execute("SELECT ROUND(AVG(final_score),1) as s FROM lms_enrollments WHERE final_score IS NOT NULL").fetchone()['s'] or 0
        pass_rate = int((completed / total_enroll) * 100) if total_enroll > 0 else 0

        # Compliance summary
        comp = conn.execute("SELECT * FROM (SELECT total_employees, compliant, compliance_pct FROM (SELECT COUNT(*) as total_employees FROM employees WHERE status='active'))").fetchone()

        # Per-course stats
        course_stats = conn.execute("""
            SELECT m.id, m.title,
                COUNT(e.id) as enrollments,
                SUM(CASE WHEN e.status='completed' THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN e.final_passed=1 THEN 1 ELSE 0 END) as passed,
                ROUND(AVG(CASE WHEN e.final_score IS NOT NULL THEN e.final_score END),1) as avg_score
            FROM elearning_modules m
            LEFT JOIN lms_enrollments e ON e.elearning_module_id=m.id
            GROUP BY m.id ORDER BY m.id
        """).fetchall()
    finally:
        conn.close()

    rows = ""
    for cs in course_stats:
        total = cs['enrollments'] or 0
        comp_count = cs['completed'] or 0
        rate = int((comp_count / total) * 100) if total > 0 else 0
        rows += f"""<tr>
            <td><strong>{cs['title']}</strong></td>
            <td>{total}</td>
            <td>{comp_count}</td>
            <td>{rate}%</td>
            <td>{cs['avg_score'] or '—'}%</td>
            <td><a href="{BASE_PATH}/lms/admin/analytics/course/{cs['id']}" class="btn btn-sm btn-primary">Details</a></td>
        </tr>"""

    body = f"""
    <div class="cards">
        <div class="card"><div class="label">Totaal Inschrijvingen</div><div class="value">{total_enroll}</div></div>
        <div class="card success"><div class="label">Voltooid</div><div class="value">{completed}</div></div>
        <div class="card warning"><div class="label">In Uitvoering</div><div class="value">{in_progress}</div></div>
        <div class="card danger"><div class="label">Gezakten</div><div class="value">{failed}</div></div>
    </div>
    <div class="cards">
        <div class="card"><div class="label">Gemiddelde Score</div><div class="value">{avg_score}%</div></div>
        <div class="card"><div class="label">Slagingspercentage</div><div class="value">{pass_rate}%</div></div>
    </div>
    <h2>Per Cursus</h2>
    <table><tr><th>Cursus</th><th>Inschrijvingen</th><th>Voltooid</th><th>Completion</th><th>Gem. Score</th><th>Details</th></tr>
    {rows or '<tr><td colspan="6" style="text-align:center;color:var(--text-muted)">Geen data</td></tr>'}
    </table>"""
    return _page('Analytics', body, 'admin-analytics')


@lms_bp.route('/admin/analytics/course/<int:course_id>')
def admin_analytics_course(course_id):
    conn = get_db()
    try:
        module = conn.execute("SELECT * FROM elearning_modules WHERE id=?", (course_id,)).fetchone()
        enrollments = conn.execute("""
            SELECT e.*, em.first_name, em.last_name, em.employee_number
            FROM lms_enrollments e
            JOIN employees em ON em.id = e.employee_id
            WHERE e.elearning_module_id=?
            ORDER BY e.status, em.last_name
        """, (course_id,)).fetchall()
        quiz_results = conn.execute("""
            SELECT qr.*, em.first_name, em.last_name
            FROM lms_quiz_results qr
            JOIN lms_enrollments enr ON enr.id = qr.enrollment_id
            JOIN employees em ON em.id = enr.employee_id
            WHERE enr.elearning_module_id=?
            ORDER BY qr.submitted_at DESC LIMIT 50
        """, (course_id,)).fetchall()
    finally:
        conn.close()

    rows = ""
    for e in enrollments:
        badge = {'not_started':'badge-muted','in_progress':'badge-info','completed':'badge-success','failed':'badge-danger'}.get(e['status'],'badge-muted')
        rows += f"""<tr>
            <td>{e['employee_number'] or ''}</td>
            <td>{e['first_name']} {e['last_name']}</td>
            <td><span class="badge {badge}">{e['status'].replace('_',' ').title()}</span></td>
            <td>{e['final_score'] or '—'}</td>
            <td>{e['progress_percent'] or 0}%</td>
        </tr>"""

    qr_rows = ""
    for qr in quiz_results:
        qr_rows += f"""<tr>
            <td>{qr['first_name']} {qr['last_name']}</td>
            <td>Poging {qr['attempt_number']}</td>
            <td>{qr['score']}%</td>
            <td>{qr['correct_answers']}/{qr['total_questions']}</td>
            <td><span class="badge {'badge-success' if qr['passed'] else 'badge-danger'}">{'✅' if qr['passed'] else '❌'}</span></td>
            <td>{qr['submitted_at'] or '—'}</td>
        </tr>"""

    title = module['title'] if module else 'Onbekend'
    body = f"""
    <h2>{title} — Cursusstatistieken</h2>
    <h2>Inschrijvingen</h2>
    <table><tr><th>Nr</th><th>Naam</th><th>Status</th><th>Score</th><th>Voortgang</th></tr>
    {rows or '<tr><td colspan="5" style="text-align:center;color:var(--text-muted)">Geen inschrijvingen</td></tr>'}
    </table>
    <h2>Recente Quiz-resultaten</h2>
    <table><tr><th>Medewerker</th><th>Poging</th><th>Score</th><th>Correct</th><th>Resultaat</th><th>Datum</th></tr>
    {qr_rows or '<tr><td colspan="6" style="text-align:center;color:var(--text-muted)">Geen quiz-resultaten</td></tr>'}
    </table>
    <a href="{BASE_PATH}/lms/admin/analytics" class="btn btn-primary" style="margin-top:16px">← Terug naar Analytics</a>"""
    return _page(f'Analytics: {title}', body, 'admin-analytics')


@lms_bp.route('/admin/analytics/employee/<int:employee_id>')
def admin_analytics_employee(employee_id):
    conn = get_db()
    try:
        emp = conn.execute("SELECT * FROM employees WHERE id=?", (employee_id,)).fetchone()
        enrollments = conn.execute("""
            SELECT e.*, m.title FROM lms_enrollments e
            JOIN elearning_modules m ON m.id = e.elearning_module_id
            WHERE e.employee_id=? ORDER BY e.status
        """, (employee_id,)).fetchall()
        certs = conn.execute("""
            SELECT c.*, m.title FROM trn_certificates c
            JOIN elearning_modules m ON m.id = c.module_id
            WHERE c.employee_id=? ORDER BY c.id DESC
        """, (employee_id,)).fetchall()
    finally:
        conn.close()

    name = f"{emp['first_name']} {emp['last_name']}" if emp else 'Onbekend'
    rows = "".join(f"""<tr>
        <td>{e['title']}</td>
        <td><span class="badge {'badge-success' if e['status']=='completed' else 'badge-info' if e['status']=='in_progress' else 'badge-muted'}">{e['status'].replace('_',' ').title()}</span></td>
        <td>{e['progress_percent'] or 0}%</td>
        <td>{e['final_score'] or '—'}</td>
    </tr>""" for e in enrollments)

    cert_rows = "".join(f"""<tr>
        <td>{c['title']}</td><td>{c['quiz_score']}%</td><td>{c['certificate_ref'] or '—'}</td>
    </tr>""" for c in certs)

    body = f"""
    <h2>{name} — Training Historie</h2>
    <h2>Inschrijvingen</h2>
    <table><tr><th>Training</th><th>Status</th><th>Voortgang</th><th>Score</th></tr>
    {rows or '<tr><td colspan="4" style="text-align:center;color:var(--text-muted)">Geen trainingen</td></tr>'}
    </table>
    <h2>Certificaten</h2>
    <table><tr><th>Training</th><th>Score</th><th>Referentie</th></tr>
    {cert_rows or '<tr><td colspan="3" style="text-align:center;color:var(--text-muted)">Geen certificaten</td></tr>'}
    </table>"""
    return _page(f'{name}', body, 'admin-analytics')


# ═══════════════════════════════════════════════════════════════════════════════
# REGISTRATION HELPER
# ═══════════════════════════════════════════════════════════════════════════════

def register_lms_routes(app):
    """Register LMS blueprint on Flask app. Call from app.py."""
    app.register_blueprint(lms_bp, url_prefix=f"{BASE_PATH}/lms")
    # Also register the API score endpoint at the top-level path
    # so existing quiz HTML files can POST to /hseq-dashboard/api/lms/score
    @app.route(f'{BASE_PATH}/api/lms/score', methods=['POST'])
    def api_lms_score_proxy():
        return api_score()
