#!/usr/bin/env python3
"""
HSEQ Intelligence Dashboard
JvG Consultancy — HSEQ Intelligence Monitor v2.0
Built by Kas, AI Operations Director
Architecture: Single-file Flask app (LGCC pattern) — inline CSS, embedded templates, render_template_string
"""

import os
import sys
import json
import uuid
import re
import urllib.request
import urllib.parse
import ssl
import tempfile
import shutil
from datetime import datetime, date

from flask import (Flask, request, render_template_string, redirect, url_for,
                   jsonify, Response, stream_with_context, send_file)
from indexer import init_db, index_file, DB_PATH, categorize
from search import (search_documents, get_document, get_categories,
                    get_authors, get_recent_documents, get_stats,
                    get_all_documents, get_db)

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024  # 50MB upload limit

# ─── Config ──────────────────────────────────────────────────────────────────
BASE_PATH = os.environ.get('BASE_PATH', '')
UPLOAD_DIR = os.path.join(os.path.dirname(__file__), 'uploads')
os.makedirs(UPLOAD_DIR, exist_ok=True)

AI_PROVIDER = os.environ.get('AI_PROVIDER', 'openrouter')
OPENROUTER_URL = os.environ.get('OPENROUTER_URL', 'https://openrouter.ai/api/v1/chat/completions')
OPENROUTER_KEY = os.environ.get('OPENROUTER_API_KEY', '')
OPENROUTER_MODEL = os.environ.get('OPENROUTER_MODEL', 'google/gemini-2.0-flash-001')
AI_API_URL = os.environ.get('AI_API_URL', 'https://api.zai.io/v1/chat/completions')
AI_API_KEY = os.environ.get('AI_API_KEY', '43a6c7e3d7b240daafae006e8488f674.ivYYRRLySgUwgqVE')
AI_MODEL = os.environ.get('AI_MODEL', 'glm-5')

# ─── HSEQ System Prompt ─────────────────────────────────────────────────────
HSEQ_SYSTEM_PROMPT = """Je bent een senior HSEQ (Health, Safety, Environment & Quality) specialist met 20+ jaar ervaring in de zware industrie, specifiek bij BRZO/Seveso-bedrijven (chemie, petrochemie, offshore, opslag van gevaarlijke stoffen).

## Jouw Expertise
- **BRZO 2015** (Besluit risico's zware ongevallen) & Seveso III richtlijn
- **ARIE** (Algemene Richtlijn Industriële Veiligheid)
- **PGS-richtlijnen** (Publieke Gezondheid & Stoffen)
- **Arbowetgeving** & Arbobesluit
- **REACH/CLP** (ECHA) & milieuregelgeving
- **MIR** (Meldplicht Incidenten Gevaarlijke Stoffen)
- **Omgevingswet** & vergunningen
- **Veiligheidsrapportages** & Company Emergency Plans

## Jouw Rol
Je helpt HSEQ Managers bij BRZO-bedrijven met:
1. Compliance-vragen over wet- en regelgeving
2. Interpretatie van richtlijnen en normen
3. Risicobeheersing en veiligheidsadvies
4. Voorbereiding op inspecties en audits
5. Documentatie- en procedurele vragen

## Communicatiestijl
- Professioneel, beknopt, autoritair in je vakgebied
- Gebruik concrete voorbeelden uit de praktijk
- Verwijs naar specifieke wetgeving/artikelen waar mogelijk
- Gebruik bronverwijzingen uit de kennisbank (zie hieronder)
- Taal: Nederlands, technische termen in het Engels waar gebruikelijk

## Belangrijk
- Als je het niet zeker weet, zeg dat eerlijk
- Raadpleeg altijd de kennisbank-bronnen voor feitelijke vragen
- Noem altijd relevante wetgeving of richtlijnen bij je antwoord
- Denk mee als een consultant: wat betekent dit voor de HSEQ Manager in de praktijk?
"""

# ─── AI Functions ────────────────────────────────────────────────────────────
def ai_call(messages, stream=False):
    """Call AI (ZAI, OpenRouter) and return response."""
    if AI_PROVIDER == 'openrouter':
        payload = json.dumps({
            "model": OPENROUTER_MODEL,
            "messages": messages,
            "stream": stream,
            "temperature": 0.7,
            "max_tokens": 4000
        }).encode('utf-8')
        req = urllib.request.Request(OPENROUTER_URL, data=payload, headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {OPENROUTER_KEY}",
            "HTTP-Referer": "https://mescalinerabbit.shop",
            "X-Title": "HSEQ Intelligence Dashboard"
        })
        resp = urllib.request.urlopen(req, timeout=60)
        return resp
    else:
        payload = json.dumps({
            "model": AI_MODEL,
            "messages": messages,
            "stream": stream,
            "temperature": 0.7,
            "max_tokens": 4000
        }).encode('utf-8')
        req = urllib.request.Request(AI_API_URL, data=payload, headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {AI_API_KEY}"
        })
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        resp = urllib.request.urlopen(req, context=ctx, timeout=120)
        return resp


def ai_complete(messages):
    """Non-streaming AI call, returns text."""
    resp = ai_call(messages, stream=False)
    data = json.loads(resp.read().decode('utf-8'))
    if AI_PROVIDER == 'ollama':
        return data['message']['content']
    return data['choices'][0]['message']['content']



# ─── SOP & Styleguide Context Loader ──────────────────────────────────────

def get_sop_context():
    """Load key SOP/Styleguide sections as persistent advisor context."""
    try:
        with open('/root/projects/jg/MASTER_SOP.md', 'r') as f:
            sop = f.read()
        with open('/root/projects/jg/MASTER_STYLEGUIDE.md', 'r') as f:
            sg = f.read()
        
        # Extract key sections only (not the full 600+ lines)
        sop_sections = []
        for line in sop.split('\n'):
            if line.startswith('## '):
                sop_sections.append(line)
            elif line.strip() and sop_sections:
                sop_sections[-1] += '\n' + line
        
        # Build compact context
        parts = ["## JvG Consultancy — MASTER SOP Referentie\n"]
        # §5 Quality Gates
        if '§5' in sop:
            start = sop.find('## §5')
            end = sop.find('## §6', start)
            if end == -1: end = sop.find('## §7', start)
            parts.append(sop[start:end].strip() + '\n')
        # §9 HSEQ Knowledge Architecture  
        if '§9' in sop:
            start = sop.find('## §9')
            end = sop.find('## §10', start)
            if end == -1: end = len(sop)
            parts.append(sop[start:end].strip() + '\n')
        # §7 Branding
        if '§7' in sop:
            start = sop.find('## §7')
            end = sop.find('## §8', start)
            if end == -1: end = sop.find('## §9', start)
            parts.append(sop[start:end].strip() + '\n')
        
        # Styleguide §1 + §8
        if '§1' in sg:
            start = sg.find('## §1')
            end = sg.find('## §2', start)
            parts.append(sg[start:end].strip() + '\n')
        if '§8' in sg:
            start = sg.find('## §8')
            end = sg.find('## §9', start)
            if end == -1: end = len(sg)
            parts.append(sg[start:end].strip() + '\n')
        
        result = '\n'.join(parts)
        if len(result) > 8000:
            result = result[:8000] + '\n[... afgekort ...]'
        return result
    except Exception as e:
        return f"[SOP niet beschikbaar: {e}]"


def get_rag_context(query, max_chars=6000):
    """Search knowledge base and return relevant chunks as context."""
    if not query or not query.strip():
        return "", []
    
    # Build multiple search queries for better recall
    import re
    stop_words = {'de', 'het', 'een', 'van', 'zijn', 'is', 'met', 'voor', 'in', 'op', 'bij', 'aan', 'te', 'en', 'of', 'wat', 'hoe', 'welke', 'welk', 'wel', 'zijn', 'niet', 'ook', 'nog', 'als', 'dan', 'maar', 'door', 'tot', 'naar', 'uit', 'over', 'dit', 'dat', 'hier', 'daar', 'kan', 'moet', 'zal', 'zou', 'kun', 'heb', 'ben', 'heb', 'meer', 'alle', 'elk', 'elke', 'veel', 'bij', 'werknemer'}
    
    # Extract meaningful terms from the query
    words = re.findall(r'\b[A-Za-zÀ-ÿ]+\b', query.lower())
    keywords = [w for w in words if w not in stop_words and len(w) > 2]
    
    # Try multiple search strategies (FTS5 uses phrase matching with quotes)
    all_results = {}
    search_queries = []
    # Individual keywords for broad matching
    for kw in keywords[:5]:
        search_queries.append(kw)
    # Two-word combinations for relevance
    for i in range(min(len(keywords)-1, 4)):
        search_queries.append(f'{keywords[i]} {keywords[i+1]}')
    # All keywords together (phrase match)
    if len(keywords) >= 2:
        search_queries.append(' '.join(keywords[:3]))
    
    seen = set()
    for sq in search_queries:
        try:
            results = search_documents(sq, page=1, per_page=5)
            for r in results['results']:
                if r['id'] not in seen:
                    all_results[r['id']] = r
                    seen.add(r['id'])
        except:
            pass
    
    if not all_results:
        return "", []
    
    context_parts = []
    sources = []
    for doc_id, r in sorted(all_results.items(), key=lambda x: x[1].get('relevance', 0), reverse=True)[:5]:
        doc_data = get_document(doc_id)
        if doc_data:
            doc = doc_data['document']
            sources.append(f"{doc.get('title', doc.get('filename', 'Onbekend'))} (ID: {doc_id})")
            title = doc.get('title') or doc.get('filename', 'Onbekend')
            category = doc.get('category', '')
            context_parts.append(f"### {title}")
            if category:
                context_parts.append(f"Categorie: {category}")
            if doc.get('author'):
                context_parts.append(f"Auteur: {doc['author']}")
            for chunk in (doc_data['chunks'] or [])[:3]:
                if chunk.get('content'):
                    context_parts.append(chunk['content'][:800])
            context_parts.append("")
    context = '\n'.join(context_parts)
    if len(context) > max_chars:
        context = context[:max_chars] + "\n\n[... afgekort wegens lengte ...]"
    return context, sources


# ─── CSS & Layout ────────────────────────────────────────────────────────────
CSS = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Inter',system-ui,sans-serif;background:#F1F3F5;color:#333;min-height:100vh}
.sidebar{position:fixed;left:0;top:0;bottom:0;width:260px;background:linear-gradient(180deg,#001F3F 0%,#003366 100%);color:#fff;padding:20px 0;z-index:100;transition:transform .3s;overflow-y:auto}
.sidebar .logo{padding:10px 24px 24px;border-bottom:1px solid rgba(255,255,255,.1)}
.sidebar .logo h2{font-size:16px;font-weight:700;margin:0}
.sidebar .logo span{color:#4ECDC4}
.sidebar .logo p{font-size:10px;color:rgba(255,255,255,.5);margin:4px 0 0}
.sidebar nav a{display:flex;align-items:center;gap:10px;padding:11px 24px;color:rgba(255,255,255,.75);text-decoration:none;font-size:13px;font-weight:500;transition:all .2s}
.sidebar nav a:hover,.sidebar nav a.active{background:rgba(255,255,255,.1);color:#fff}
.sidebar nav a .emoji{font-size:17px;width:24px;text-align:center}
.main{margin-left:260px;min-height:100vh}
.header{background:#fff;padding:16px 32px;border-bottom:1px solid #E9ECEF;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:50}
.header h1{font-size:18px;font-weight:600;color:#003366}
.header .subtitle{font-size:11px;color:#868E96;margin-top:2px}
.content{padding:24px 32px;max-width:1400px}
.card{background:#fff;border-radius:10px;padding:20px;margin-bottom:16px;box-shadow:0 1px 3px rgba(0,0,0,.06);border:1px solid #E9ECEF}
.card h2{font-size:16px;font-weight:600;color:#003366;margin-bottom:12px}
.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.stat-card{background:#fff;border-radius:10px;padding:16px;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.06);border:1px solid #E9ECEF}
.stat-card .value{font-size:28px;font-weight:700;color:#003366}
.stat-card .label{font-size:11px;color:#868E96;margin-top:4px;text-transform:uppercase;letter-spacing:.5px}
.btn{display:inline-flex;align-items:center;gap:6px;padding:8px 16px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;border:none;text-decoration:none;transition:all .2s;font-family:inherit}
.btn-primary{background:#003366;color:#fff}.btn-primary:hover{background:#004488}
.btn-outline{background:transparent;color:#003366;border:1px solid #003366}.btn-outline:hover{background:#003366;color:#fff}
.btn-success{background:#2B8A3E;color:#fff}.btn-success:hover{background:#37B24D}
.btn-danger{background:#E03131;color:#fff}.btn-danger:hover{background:#FA5252}
.btn-sm{padding:4px 10px;font-size:11px}
.form-control{border:1px solid #DEE2E6;border-radius:6px;padding:8px 12px;font-size:13px;font-family:inherit;outline:none;width:100%}
.form-control:focus{border-color:#003366;box-shadow:0 0 0 3px rgba(0,51,102,.1)}
table{width:100%;border-collapse:collapse}
th{background:#003366;color:#fff;padding:10px 12px;text-align:left;font-size:12px;font-weight:600;white-space:nowrap}
td{padding:10px 12px;border-bottom:1px solid #E9ECEF;font-size:13px}
tr:hover td{background:#F8F9FA}
.badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:600}
.badge-procedures{background:#D0EBFF;color:#1864AB}
.badge-wetgeving{background:#D3F9D8;color:#2B8A3E}
.badge-scraped{background:#FFF3BF;color:#E67700}
.badge-arbeidsgroepen{background:#FFE8CC;color:#D9480F}
.badge-overig{background:#F1F3F5;color:#495057}
.page-nav{display:flex;gap:4px;justify-content:center;margin-top:16px}
.page-nav a,.page-nav span{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;padding:0 8px;border-radius:6px;font-size:12px;text-decoration:none;border:1px solid #DEE2E6;color:#495057}
.page-nav a:hover{background:#003366;color:#fff;border-color:#003366}
.page-nav .active{background:#003366;color:#fff;border-color:#003366}
.search-bar{display:flex;gap:8px;margin-bottom:16px}
.search-bar input{flex:1}
.cat-pills{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px}
.cat-pill{display:inline-block;padding:5px 12px;border-radius:16px;font-size:11px;font-weight:500;cursor:pointer;text-decoration:none;border:1px solid #DEE2E6;color:#495057;transition:all .2s}
.cat-pill:hover,.cat-pill.active{background:#003366;color:#fff;border-color:#003366}
.empty-state{text-align:center;padding:48px 24px;color:#868E96}
.empty-state .emoji{font-size:48px;margin-bottom:12px}
.empty-state h3{color:#495057;margin-bottom:8px}
.empty-state p{font-size:13px}
@keyframes bounce{0%,80%,100%{transform:translateY(0)}40%{transform:translateY(-6px)}}
@keyframes spin{to{transform:rotate(360deg)}}
.upload-zone{border:2px dashed #CED4DA;border-radius:10px;padding:32px;text-align:center;cursor:pointer;transition:all .2s;background:#FAFBFC}
.upload-zone:hover,.upload-zone.dragover{border-color:#003366;background:#F0F4F8}
.upload-zone .emoji{font-size:36px;margin-bottom:8px}
.upload-zone p{font-size:13px;color:#495057}
.upload-zone small{font-size:11px;color:#868E96}
.upload-progress{height:6px;background:#E9ECEF;border-radius:3px;overflow:hidden;margin-top:12px}
.upload-progress .bar{height:100%;background:#003366;border-radius:3px;transition:width .3s}
/* Chat styles */
#hseqMessages .msg{max-width:88%;padding:12px 16px;border-radius:12px;font-size:13px;line-height:1.65;overflow-wrap:break-word;word-break:break-word}
#hseqMessages .msg.user{align-self:flex-end;background:#003366;color:#fff;border-bottom-right-radius:4px}
#hseqMessages .msg.assistant{align-self:flex-start;background:#fff;color:#333;border:1px solid #E9ECEF;border-bottom-left-radius:4px;box-shadow:0 1px 3px rgba(0,0,0,.04)}
#hseqMessages .msg.assistant h1,#hseqMessages .msg.assistant h2,#hseqMessages .msg.assistant h3{font-size:14px;font-weight:700;color:#003366;margin:12px 0 6px 0}
#hseqMessages .msg.assistant h1:first-child,#hseqMessages .msg.assistant h2:first-child,#hseqMessages .msg.assistant h3:first-child{margin-top:0}
#hseqMessages .msg.assistant p{margin:4px 0}
#hseqMessages .msg.assistant ul,#hseqMessages .msg.assistant ol{margin:4px 0 4px 18px;padding:0}
#hseqMessages .msg.assistant li{margin:3px 0}
#hseqMessages .msg.assistant strong{color:#003366}
#hseqMessages .msg.assistant table{border-collapse:collapse;width:100%;margin:8px 0;font-size:12px}
#hseqMessages .msg.assistant th{background:#003366;color:#fff;padding:6px 10px;text-align:left;font-weight:600}
#hseqMessages .msg.assistant td{padding:5px 10px;border-bottom:1px solid #E9ECEF}
#hseqMessages .msg.assistant tr:nth-child(even) td{background:#F8F9FA}
#hseqMessages .msg.assistant .source-ref{display:block;margin-top:8px;padding-top:6px;border-top:1px solid #DEE2E6;font-size:11px;color:#868E96;font-style:italic}
/* Mobile */
@media(max-width:768px){
  .sidebar{transform:translateX(-100%)}
  .sidebar.open{transform:translateX(0)}
  .main{margin-left:0}
  .content{padding:16px}
  .stats-grid{grid-template-columns:repeat(2,1fr)}
}
"""

# ─── Page Template (LGCC pattern) ───────────────────────────────────────────
PAGE_TEMPLATE = """<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>{{page_title}} — HSEQ Intelligence Dashboard</title>
<style>{{css}}</style>
</head>
<body>
<!-- Sidebar -->
<div class="sidebar" id="sidebar">
  <div class="logo">
    <h2><span>🛡️</span> HSEQ Intelligence</h2>
    <p>JvG Consultancy — Dashboard v2.0</p>
  </div>
  <nav>
    <a href="{{BASE_PATH}}/" class="{{'active' if active=='dashboard' else ''}}"><span class="emoji">📊</span> Dashboard</a>
    <div style="padding:12px 24px 6px;font-size:10px;text-transform:uppercase;letter-spacing:1px;color:rgba(255,255,255,.4);margin-top:8px">Diensten</div>
    <a href="{{BASE_PATH}}/services/arbo" class="{{'active' if active=='arbo' else ''}}"><span class="emoji">👷</span> Arbo & Veiligheid</a>
    <a href="{{BASE_PATH}}/services/brzo" class="{{'active' if active=='brzo' else ''}}"><span class="emoji">🏭</span> BRZO / Seveso</a>
    <a href="{{BASE_PATH}}/services/milieu" class="{{'active' if active=='milieu' else ''}}"><span class="emoji">🌿</span> Milieu & Omgeving</a>
    <a href="{{BASE_PATH}}/services/kam" class="{{'active' if active=='kam' else ''}}"><span class="emoji">📋</span> KAM Management</a>
    <a href="{{BASE_PATH}}/services/training" class="{{'active' if active=='training' else ''}}"><span class="emoji">🎓</span> Training & Opleiding</a>
    <a href="{{BASE_PATH}}/services/energy" class="{{'active' if active=='energy' else ''}}"><span class="emoji">⚡</span> Energie & Proces</a>
    <div style="padding:12px 24px 6px;font-size:10px;text-transform:uppercase;letter-spacing:1px;color:rgba(255,255,255,.4);margin-top:8px">Tools</div>
    <a href="{{BASE_PATH}}/knowledge" class="{{'active' if active=='knowledge' else ''}}"><span class="emoji">📚</span> Kennisbank</a>
    <a href="{{BASE_PATH}}/upload" class="{{'active' if active=='upload' else ''}}"><span class="emoji">📤</span> Upload</a>
    <a href="{{BASE_PATH}}/advisor" class="{{'active' if active=='advisor' else ''}}"><span class="emoji">🧠</span> HSEQ Advisor</a>
  </nav>
</div>

<!-- Mobile menu toggle -->
<button onclick="document.getElementById('sidebar').classList.toggle('open')" style="display:none;position:fixed;top:12px;left:12px;z-index:200;background:#003366;color:#fff;border:none;border-radius:8px;width:40px;height:40px;font-size:18px;cursor:pointer" id="menuBtn">☰</button>

<!-- Main -->
<div class="main">
  <div class="header">
    <div>
      <h1>{{page_title}}</h1>
      {% if page_subtitle %}<div class="subtitle">{{page_subtitle}}</div>{% endif %}
    </div>
    <div style="font-size:12px;color:#868E96">{{now}}</div>
  </div>
  <div class="content">
    {{page_body|safe}}
  </div>
</div>

<script>
// Mobile detection
if(window.innerWidth<=768){document.getElementById('menuBtn').style.display='block'}
window.addEventListener('resize',function(){document.getElementById('menuBtn').style.display=window.innerWidth<=768?'block':'none';if(window.innerWidth>768)document.getElementById('sidebar').classList.remove('open')});
</script>
</body>
</html>
"""


# ─── Helper: page() ─────────────────────────────────────────────────────────
def page(body_html, active='dashboard', page_title='Dashboard', page_subtitle=None, **kwargs):
    """Render page with layout template (LGCC pattern)."""
    if page_subtitle is None:
        page_subtitle = 'JvG Consultancy — HSEQ Intelligence Dashboard'
    kwargs['BASE_PATH'] = BASE_PATH
    body_rendered = render_template_string(body_html, **kwargs)
    kwargs['active'] = active
    kwargs['now'] = datetime.now().strftime('%d %B %Y')
    kwargs['css'] = CSS
    kwargs['page_body'] = body_rendered
    kwargs['page_title'] = page_title
    kwargs['page_subtitle'] = page_subtitle
    kwargs['BASE_PATH'] = BASE_PATH
    return render_template_string(PAGE_TEMPLATE, **kwargs)


# ─── Init DB ────────────────────────────────────────────────────────────────
@app.before_request
def ensure_db():
    if not os.path.exists(DB_PATH):
        init_db()


# ═══════════════════════════════════════════════════════════════════════════
# DASHBOARD
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/')
def dashboard():
    stats = get_stats()
    categories = get_categories()
    recent = get_recent_documents(limit=8)
    return page("""

<!-- Stats -->
<div class="stats-grid">
  <div class="stat-card">
    <div class="value">{{stats['total_documents']}}</div>
    <div class="label">Documenten</div>
  </div>
  <div class="stat-card">
    <div class="value">{{stats['total_categories']}}</div>
    <div class="label">Categorieën</div>
  </div>
  <div class="stat-card">
    <div class="value">{{'%d' % (stats['total_pages'] or 0)}}</div>
    <div class="label">Totale Pagina's</div>
  </div>
  <div class="stat-card">
    <div class="value">{{'%.1f MB' % ((stats['total_size'] or 0) / 1048576)}}</div>
    <div class="label">Totale Grootte</div>
  </div>
</div>

<!-- Categorieën -->
<div class="card">
  <h2>📂 Categorieën</h2>
  <div class="cat-pills">
    {% for cat in categories %}
    <a href="{{BASE_PATH}}/knowledge?category={{cat['category']|urlencode}}" class="cat-pill">{{cat['category']}} ({{cat['count']}})</a>
    {% endfor %}
  </div>
</div>

<!-- Recente documenten -->
<div class="card">
  <h2>🕐 Recente Documenten</h2>
  {% if recent %}
  <table>
    <thead><tr><th>Document</th><th>Categorie</th><th>Pag.</th><th>Grootte</th><th>Geïndexeerd</th></tr></thead>
    <tbody>
    {% for doc in recent %}
    <tr>
      <td><a href="{{BASE_PATH}}/document/{{doc['id']}}" style="color:#003366;font-weight:500;text-decoration:none">{{doc.get('title') or doc.get('filename','—')}}</a></td>
      <td><span class="badge badge-{{doc['category'].lower()|replace(' ','_')|replace('& ','') if doc.get('category') else 'overig'}}">{{doc.get('category','—')}}</span></td>
      <td>{{doc.get('pages','—')}}</td>
      <td>{{'%.0f KB' % ((doc.get('file_size',0) or 0)/1024) if doc.get('file_size') else '—'}}</td>
      <td style="font-size:11px;color:#868E96">{{doc.get('indexed_date','')[:10] if doc.get('indexed_date') else '—'}}</td>
    </tr>
    {% endfor %}
    </tbody>
  </table>
  <div style="margin-top:12px"><a href="{{BASE_PATH}}/knowledge" class="btn btn-outline">Bekijk alle documenten →</a></div>
  {% else %}
  <div class="empty-state"><div class="emoji">📭</div><h3>Nog geen documenten</h3><p>Upload PDF's om te beginnen.</p></div>
  {% endif %}
</div>

<!-- Diensten Grid (KWA-stijl) -->
<div class="card">
  <h2>🔧 Onze Diensten</h2>
  <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px">
    <a href="{{BASE_PATH}}/services/arbo" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #003366;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(0,51,102,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">👷</div><h3 style="font-size:13px;color:#003366;margin:0 0 4px">Arbo & Veiligheid</h3><p style="font-size:11px;color:#868E96;margin:0">RI&E, arbeidshygiëne, PBM</p></a>
    <a href="{{BASE_PATH}}/services/brzo" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #E03131;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(224,49,49,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">🏭</div><h3 style="font-size:13px;color:#E03131;margin:0 0 4px">BRZO / Seveso</h3><p style="font-size:11px;color:#868E96;margin:0">Veiligheidsrapport, QRA, ARIE</p></a>
    <a href="{{BASE_PATH}}/services/milieu" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #2B8A3E;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(43,138,62,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">🌿</div><h3 style="font-size:13px;color:#2B8A3E;margin:0 0 4px">Milieu & Omgeving</h3><p style="font-size:11px;color:#868E96;margin:0">Vergunningen, emissies, MER</p></a>
    <a href="{{BASE_PATH}}/services/kam" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #4263EB;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(66,99,235,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">📋</div><h3 style="font-size:13px;color:#4263EB;margin:0 0 4px">KAM Management</h3><p style="font-size:11px;color:#868E96;margin:0">ISO, audits, compliance</p></a>
    <a href="{{BASE_PATH}}/services/training" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #F76707;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(247,103,7,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">🎓</div><h3 style="font-size:13px;color:#F76707;margin:0 0 4px">Training & Opleiding</h3><p style="font-size:11px;color:#868E96;margin:0">Toolbox talks, VCA, e-learning</p></a>
    <a href="{{BASE_PATH}}/services/energy" class="card" style="text-decoration:none;cursor:pointer;border-left:3px solid #F59F00;transition:all .2s" onmouseover="this.style.transform='translateY(-2px)';this.style.boxShadow='0 4px 12px rgba(245,159,0,.12)'" onmouseout="this.style.transform='';this.style.boxShadow=''"><div style="font-size:20px;margin-bottom:4px">⚡</div><h3 style="font-size:13px;color:#F59F00;margin:0 0 4px">Energie & Proces</h3><p style="font-size:11px;color:#868E96;margin:0">Energieaudit, procesanalyse</p></a>
  </div>
</div>

""", page_title='Dashboard', active='dashboard', stats=stats, categories=categories, recent=recent)


# ═══════════════════════════════════════════════════════════════════════════
# KNOWLEDGE BASE (Browse + Search)
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/knowledge')
def knowledge():
    q = request.args.get('q', '').strip()
    category = request.args.get('category', '').strip()
    page_num = request.args.get('page', 1, type=int)
    if page_num < 1: page_num = 1

    categories = get_categories()

    if q:
        results = search_documents(q, category=category or None, page=page_num, per_page=20)
        is_search = True
    else:
        results = get_all_documents(category=category or None, page=page_num, per_page=20)
        is_search = False

    return page("""

<!-- Search -->
<div class="search-bar">
  <form method="get" action="{{BASE_PATH}}/knowledge" style="display:flex;gap:8px;flex:1">
    <input type="text" name="q" value="{{q}}" placeholder="Zoek in kennisbank..." class="form-control" style="flex:1">
    <button type="submit" class="btn btn-primary">🔍 Zoeken</button>
    {% if q %}
    <a href="{{BASE_PATH}}/knowledge" class="btn btn-outline">✕</a>
    {% endif %}
  </form>
</div>

<!-- Categorie filter -->
<div class="cat-pills">
  <a href="{{BASE_PATH}}/knowledge{% if q %}?q={{q}}{% endif %}" class="cat-pill {{'active' if not category else ''}}">Alle ({{results['total']}})</a>
  {% for cat in categories %}
  <a href="{{BASE_PATH}}/knowledge?category={{cat['category']|urlencode}}{% if q %}&q={{q}}{% endif %}" class="cat-pill {{'active' if category == cat['category'] else ''}}">{{cat['category']}} ({{cat['count']}})</a>
  {% endfor %}
</div>

<!-- Results -->
<div class="card">
  {% if is_search %}
  <h2>🔍 Zoekresultaten: "{{q}}" — {{results['total']}} resultaten</h2>
  {% else %}
  <h2>📚 Kennisbank — {{results['total']}} documenten</h2>
  {% endif %}

  {% if results['results'] %}
  <table>
    <thead><tr><th>Document</th><th>Categorie</th><th>Auteur</th><th>Pag.</th><th>Preview</th></tr></thead>
    <tbody>
    {% for doc in results['results'] %}
    <tr>
      <td><a href="{{BASE_PATH}}/document/{{doc['id']}}{% if q %}?q={{q}}{% endif %}" style="color:#003366;font-weight:500;text-decoration:none">{{doc.get('title') or doc.get('filename','—')}}</a></td>
      <td><span class="badge badge-overig">{{doc.get('category','—')}}</span></td>
      <td style="font-size:12px">{{doc.get('author','—') or '—'}}</td>
      <td>{{doc.get('pages','—')}}</td>
      <td style="font-size:11px;color:#868E96;max-width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">{{doc.get('preview','')[:100] if doc.get('preview') else (doc.get('snippet','')[:100] if doc.get('snippet') else '')}}</td>
    </tr>
    {% endfor %}
    </tbody>
  </table>

  <!-- Pagination -->
  {% if results['pages'] > 1 %}
  <div class="page-nav">
    {% if results['page'] > 1 %}
    <a href="{{BASE_PATH}}/knowledge?page={{results['page']-1}}{% if q %}&q={{q}}{% endif %}{% if category %}&category={{category}}{% endif %}">←</a>
    {% endif %}
    {% for p in range(1, results['pages']+1) %}
      {% if p == results['page'] %}
      <span class="active">{{p}}</span>
      {% elif p <= 3 or p >= results['pages']-2 or (p >= results['page']-1 and p <= results['page']+1) %}
      <a href="{{BASE_PATH}}/knowledge?page={{p}}{% if q %}&q={{q}}{% endif %}{% if category %}&category={{category}}{% endif %}">{{p}}</a>
      {% elif p == 4 or p == results['pages']-3 %}
      <span>…</span>
      {% endif %}
    {% endfor %}
    {% if results['page'] < results['pages'] %}
    <a href="{{BASE_PATH}}/knowledge?page={{results['page']+1}}{% if q %}&q={{q}}{% endif %}{% if category %}&category={{category}}{% endif %}">→</a>
    {% endif %}
  </div>
  {% endif %}

  {% else %}
  <div class="empty-state">
    <div class="emoji">{{'🔍' if q else '📭'}}</div>
    <h3>{{'Geen resultaten gevonden' if q else 'Nog geen documenten'}}</h3>
    <p>{{'Probeer een andere zoekterm of breid de zoekopdracht uit.' if q else 'Upload PDF\\'s om te beginnen.'}}</p>
  </div>
  {% endif %}
</div>

""", page_title='Kennisbank', active='knowledge', q=q, category=category,
   categories=categories, results=results, is_search=bool(q), BASE_PATH=BASE_PATH)


# ═══════════════════════════════════════════════════════════════════════════
# DOCUMENT VIEWER
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/document/<int:doc_id>')
def document(doc_id):
    data = get_document(doc_id)
    if not data:
        return page('<div class="empty-state"><div class="emoji">❌</div><h3>Document niet gevonden</h3></div>'), 404
    doc = data['document']
    chunks = data['chunks']
    highlight_q = request.args.get('q', '').strip()
    return page("""

<div style="margin-bottom:16px">
  <a href="{{BASE_PATH}}/knowledge" class="btn btn-outline btn-sm">← Terug naar kennisbank</a>
</div>

<div class="card">
  <h2>{{doc.get('title') or doc.get('filename','—')}}</h2>
  <div style="display:flex;gap:12px;flex-wrap:wrap;margin:12px 0;font-size:12px;color:#868E96">
    {% if doc.get('filename') %}<span>📄 {{doc['filename']}}</span>{% endif %}
    {% if doc.get('author') %}<span>✍️ {{doc['author']}}</span>{% endif %}
    {% if doc.get('category') %}<span>📂 {{doc['category']}}</span>{% endif %}
    {% if doc.get('pages') %}<span>📑 {{doc['pages']}} pagina's</span>{% endif %}
    {% if doc.get('file_size') %}<span>💾 {{'%.0f KB' % (doc['file_size']/1024)}}</span>{% endif %}
    {% if doc.get('indexed_date') %}<span>🕐 Geïndexeerd: {{doc['indexed_date'][:10]}}</span>{% endif %}
  </div>
</div>

<!-- Chunks / Content -->
{% for chunk in chunks %}
<div class="card">
  <h3 style="font-size:14px;color:#003366;margin-bottom:8px">{{chunk.get('title','') or 'Chunk ' + (chunk.get('chunk_index',loop.index)|string)}}</h3>
  <div style="font-size:13px;line-height:1.7;color:#333;white-space:pre-wrap;max-height:600px;overflow-y:auto">{{chunk.get('content','')|safe}}</div>
</div>
{% endfor %}

{% if not chunks %}
<div class="card">
  <div style="font-size:13px;line-height:1.7;color:#333;white-space:pre-wrap;max-height:800px;overflow-y:auto">{{doc.get('full_text','Geen content beschikbaar.')}}</div>
</div>
{% endif %}

""", page_title=doc.get('title', doc.get('filename', 'Document')),
   active='knowledge', doc=doc, chunks=chunks, highlight_q=highlight_q, BASE_PATH=BASE_PATH)


# ═══════════════════════════════════════════════════════════════════════════
# UPLOAD
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/upload')
def upload_page():
    return page("""

<div class="card">
  <h2>📤 Document Upload</h2>
  <p style="font-size:13px;color:#868E96;margin-bottom:16px">Upload PDF-documenten om toe te voegen aan de HSEQ Kennisbank. Documenten worden automatisch geïndexeerd en doorzoekbaar.</p>

  <div class="upload-zone" id="dropZone" onclick="document.getElementById('fileInput').click()">
    <div class="emoji">📁</div>
    <p>Sleep PDF-bestanden hierheen of klik om te selecteren</p>
    <small>Max. 50 MB per bestand • PDF-formaat</small>
    <input type="file" id="fileInput" accept=".pdf" multiple style="display:none" onchange="handleFiles(this.files)">
  </div>

  <div id="uploadProgress" style="display:none;margin-top:16px">
    <div class="upload-progress"><div class="bar" id="progressBar" style="width:0%"></div></div>
    <p id="uploadStatus" style="font-size:12px;color:#868E96;margin-top:8px">Bezig met uploaden...</p>
  </div>

  <div id="uploadResults" style="margin-top:16px"></div>
</div>

<script>
var BASE = '{{BASE_PATH}}';

// Drag & drop
var dropZone = document.getElementById('dropZone');
['dragenter','dragover'].forEach(function(e){
  dropZone.addEventListener(e, function(ev){ev.preventDefault();dropZone.classList.add('dragover')});
});
['dragleave','drop'].forEach(function(e){
  dropZone.addEventListener(e, function(ev){ev.preventDefault();dropZone.classList.remove('dragover')});
});
dropZone.addEventListener('drop', function(ev){
  var files = ev.dataTransfer.files;
  handleFiles(files);
});

function handleFiles(files){
  if(!files || !files.length) return;
  var formData = new FormData();
  for(var i=0;i<files.length;i++){
    if(files[i].type !== 'application/pdf'){alert(files[i].name + ' is geen PDF.');continue}
    formData.append('files', files[i]);
  }
  if(!formData.has('files')) return;

  document.getElementById('uploadProgress').style.display = 'block';
  document.getElementById('progressBar').style.width = '30%';
  document.getElementById('uploadStatus').textContent = 'Bezig met uploaden...';
  document.getElementById('uploadResults').innerHTML = '';

  var xhr = new XMLHttpRequest();
  xhr.open('POST', BASE + '/api/upload');
  xhr.onload = function(){
    document.getElementById('progressBar').style.width = '100%';
    try {
      var data = JSON.parse(xhr.responseText);
      if(data.success){
        document.getElementById('uploadStatus').innerHTML = '<span style="color:#2B8A3E">✅ ' + (data.indexed||0) + ' documenten geïndexeerd</span>';
        var html = '<div class="card" style="margin-top:12px"><h3 style="font-size:14px">Upload Resultaat</h3><table><thead><tr><th>Bestand</th><th>Status</th><th>Categorie</th></tr></thead><tbody>';
        (data.results||[]).forEach(function(r){
          html += '<tr><td>'+r.filename+'</td><td>'+(r.success?'<span style="color:#2B8A3E">✅ OK</span>':'<span style="color:#E03131">❌ '+r.error+'</span>')+'</td><td>'+(r.category||'—')+'</td></tr>';
        });
        html += '</tbody></table></div>';
        document.getElementById('uploadResults').innerHTML = html;
      } else {
        document.getElementById('uploadStatus').innerHTML = '<span style="color:#E03131">❌ ' + (data.error||'Upload mislukt') + '</span>';
      }
    } catch(e){
      document.getElementById('uploadStatus').textContent = 'Upload voltooid.';
    }
  };
  xhr.onerror = function(){
    document.getElementById('uploadStatus').innerHTML = '<span style="color:#E03131">❌ Netwerkfout</span>';
  };
  xhr.upload.onprogress = function(e){
    if(e.lengthComputable){
      document.getElementById('progressBar').style.width = Math.round(e.loaded/e.total*70) + '%';
    }
  };
  xhr.send(formData);
}
</script>

""", page_title='Upload', active='upload', BASE_PATH=BASE_PATH)


@app.route('/api/upload', methods=['POST'])
def api_upload():
    """Handle PDF upload and indexing."""
    if 'files' not in request.files:
        return jsonify({'success': False, 'error': 'Geen bestanden ontvangen'}), 400

    files = request.files.getlist('files')
    if not files:
        return jsonify({'success': False, 'error': 'Geen bestanden geselecteerd'}), 400

    results = []
    indexed = 0
    init_db()

    for f in files:
        if not f.filename or not f.filename.lower().endswith('.pdf'):
            results.append({'filename': f.filename, 'success': False, 'error': 'Geen PDF'})
            continue

        # Save to temp file
        temp_path = os.path.join(UPLOAD_DIR, f.filename)
        try:
            f.save(temp_path)
            # Index the file
            result = index_file(temp_path, original_filename=f.filename)
            if result and result.get('success'):
                indexed += 1
                results.append({
                    'filename': f.filename,
                    'success': True,
                    'category': result.get('category', categorize(f.filename)),
                    'pages': result.get('pages', 0)
                })
            else:
                results.append({'filename': f.filename, 'success': False, 'error': result.get('error', 'Indexering mislukt') if result else 'Onbekende fout'})
        except Exception as e:
            results.append({'filename': f.filename, 'success': False, 'error': str(e)})
        finally:
            if os.path.exists(temp_path):
                os.remove(temp_path)

    return jsonify({
        'success': indexed > 0,
        'indexed': indexed,
        'total': len(files),
        'results': results
    })


# ═══════════════════════════════════════════════════════════════════════════
# HSEQ ADVISOR (RAG Chat)
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/advisor')
def advisor():
    return page("""

<div class="card" style="grid-column:1/-1">
  <div style="display:flex;align-items:center;gap:12px;margin-bottom:16px">
    <div style="width:48px;height:48px;border-radius:50%;background:linear-gradient(135deg,#003366,#4ECDC4);display:flex;align-items:center;justify-content:center;font-size:24px">🧠</div>
    <div>
      <h2 style="margin:0">HSEQ Advisor</h2>
      <p style="margin:0;font-size:12px;color:#868E96">Je senior HSEQ specialist — gestructureerd advies op basis van BRZO, Seveso, Arbo & de kennisbank</p>
    </div>
  </div>

  <!-- Categorie tabs -->
  <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px">
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'')" style="font-size:11px">📋 Algemeen</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'brzo')" style="font-size:11px">🏭 BRZO/Seveso</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'arbo')" style="font-size:11px">👷 Arbowetgeving</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'gevaarlijk')" style="font-size:11px">☢️ Gevaarlijke Stoffen</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'milieu')" style="font-size:11px">🌿 Milieu & Omgeving</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'ongeval')" style="font-size:11px">🚨 Incidenten & Ongelukken</button>
    <button class="btn btn-outline btn-sm hseq-cat" onclick="setHseqCat(this,'training')" style="font-size:11px">🎓 Training & Opleiding</button>
  </div>

  <!-- Chat -->
  <div style="border:1px solid #E9ECEF;border-radius:10px;overflow:hidden;background:#fff">
    <!-- Header -->
    <div style="background:linear-gradient(135deg,#003366,#005580);color:#fff;padding:12px 16px;display:flex;justify-content:space-between;align-items:center">
      <div style="display:flex;align-items:center;gap:8px">
        <span style="font-size:16px">🧠</span>
        <span style="font-size:13px;font-weight:600">HSEQ Advisor Chat</span>
        <span id="hseqCatBadge" style="font-size:10px;background:rgba(255,255,255,.2);padding:2px 8px;border-radius:10px;display:none"></span>
      </div>
      <div style="display:flex;gap:6px">
        <button onclick="clearHseqChat()" style="background:rgba(255,255,255,.15);border:none;color:#fff;border-radius:4px;padding:4px 10px;font-size:11px;cursor:pointer">🔄 Nieuw</button>
        <button onclick="exportHseqChat()" style="background:rgba(255,255,255,.15);border:none;color:#fff;border-radius:4px;padding:4px 10px;font-size:11px;cursor:pointer">📥 Export</button>
      </div>
    </div>

    <!-- Messages -->
    <div id="hseqMessages" style="height:450px;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;background:#FAFBFC">
      <div class="msg assistant" style="background:#fff;border:1px solid #E9ECEF;box-shadow:0 1px 3px rgba(0,0,0,.06)">
        <div style="font-weight:600;margin-bottom:8px;color:#003366">🧠 HSEQ Advisor</div>
        <div style="font-size:13px;line-height:1.6">
          Welkom! Ik ben je senior HSEQ specialist, gespecialiseerd in BRZO/Seveso-bedrijven in de zware industrie. Kies een <strong>categorie</strong> of stel direct je vraag.<br><br>
          💡 <em>Tip: Ik raadpleeg automatisch de kennisbank voor relevante documenten en wetgeving.</em>
        </div>
      </div>
    </div>

    <!-- Typing -->
    <div id="hseqTyping" style="display:none;padding:8px 16px;background:#FAFBFC;border-top:1px solid #F1F3F5">
      <div style="display:flex;align-items:center;gap:6px;font-size:12px;color:#868E96">
        <span style="display:inline-flex;gap:3px"><span style="width:6px;height:6px;border-radius:50%;background:#003366;animation:bounce 1s infinite">.</span><span style="width:6px;height:6px;border-radius:50%;background:#003366;animation:bounce 1s infinite .2s">.</span><span style="width:6px;height:6px;border-radius:50%;background:#003366;animation:bounce 1s infinite .4s">.</span></span>
        Advisor denkt na...
      </div>
    </div>

    <!-- Input -->
    <div style="padding:12px;border-top:1px solid #E9ECEF;display:flex;gap:8px;background:#fff">
      <input type="text" id="hseqInput" class="form-control" placeholder="Stel je HSEQ vraag..." style="flex:1;border-radius:20px;padding:10px 16px" onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendHseqMessage()}">
      <button class="btn btn-primary" onclick="sendHseqMessage()" style="border-radius:50%;width:40px;height:40px;min-width:40px;padding:0;display:flex;align-items:center;justify-content:center" id="hseqSendBtn">➤</button>
    </div>
  </div>
</div>

<script>
var BASE = '{{BASE_PATH}}';
var hseqHistory = [];
var hseqCurrentCat = '';

var HSEQ_CATEGORIES = {
  'brzo': {label: 'BRZO/Seveso', context: 'Focus op BRZO 2015, Seveso III, ARIE, veiligheidsrapportages, company emergency plans, externe veiligheid.'},
  'arbo': {label: 'Arbowetgeving', context: 'Focus op Arbowet, Arbobesluit, RI&E, arbeidsomstandigheden, werkgeversverantwoordelijkheden.'},
  'gevaarlijk': {label: 'Gevaarlijke Stoffen', context: 'Focus op REACH, CLP, PGS-richtlijnen, SDS/MSDS, classificatie etikettering, opslag.'},
  'milieu': {label: 'Milieu', context: 'Focus op Omgevingswet, milieuvergunningen, emissies, afval, bodembescherming, MER.'},
  'ongeval': {label: 'Incidenten', context: 'Focus op MIR meldplicht, ongevallenonderzoek, root cause analysis, veiligheids cultuur.'},
  'training': {label: 'Training', context: 'Focus op veiligheidstrainingen, toolbox talks, competentie-eisen, instructie en voorlichting.'}
};

function setHseqCat(btn, cat) {
  hseqCurrentCat = cat;
  document.querySelectorAll('.hseq-cat').forEach(function(b){b.classList.remove('active');b.style.background='';b.style.color=''});
  btn.classList.add('active');
  btn.style.background='#003366';btn.style.color='#fff';
  var badge = document.getElementById('hseqCatBadge');
  if(cat && HSEQ_CATEGORIES[cat]){badge.textContent=HSEQ_CATEGORIES[cat].label;badge.style.display='inline'}
  else{badge.style.display='none'}
}

function escHtml(t){var d=document.createElement('div');d.textContent=t;return d.innerHTML}

function renderHseqMarkdown(text){
  if(!text) return '';
  var h = text;
  h = h.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  // Tables
  h = h.replace(/^\|(.+)\|$/gm, function(m,row){
    if(row.match(/^[-:\s|]+$/)) return '';
    var cells = row.split('|').filter(function(c){return c.trim()});
    var isHeader = m.indexOf('---')===-1;
    return '<tr>' + cells.map(function(c){return '<'+(isHeader?'th':'td')+'>'+c.trim()+'</'+(isHeader?'th':'td')+'>';}).join('') + '</tr>';
  });
  h = h.replace(/((<tr>.*?<\/tr>\s*)+)/g, '<table>$1</table>');
  h = h.replace(/^### (.*)/gm,'<h3>$1</h3>');
  h = h.replace(/^## (.*)/gm,'<h2>$1</h2>');
  h = h.replace(/^# (.*)/gm,'<h1>$1</h1>');
  h = h.replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>');
  h = h.replace(/\*(.+?)\*/g,'<em>$1</em>');
  h = h.replace(/^---$/gm,'<hr>');
  h = h.replace(/^[-•] (.*)/gm,'<li>$1</li>');
  h = h.replace(/(<li>.*<\/li>\s*)+/g,'<ul>$&</ul>');
  h = h.replace(/^\d+\. (.*)/gm,'<li>$1</li>');
  h = h.replace(/^&gt; (.*)/gm,'<blockquote>$1</blockquote>');
  h = h.replace(/```(\w*)\n([\s\S]*?)```/g,'<pre><code>$2</code></pre>');
  h = h.replace(/`([^`]+)`/g,'<code>$1</code>');
  h = h.replace(/\n\n/g,'</p><p>');
  h = h.replace(/\n/g,'<br>');
  h = '<p>'+h+'</p>';
  h = h.replace(/<p>\s*<\/p>/g,'');
  return h;
}

function sendHseqMessage(){
  var input = document.getElementById('hseqInput');
  var msg = input.value.trim();
  if(!msg) return;
  input.value = '';
  document.getElementById('hseqSendBtn').disabled = true;

  var container = document.getElementById('hseqMessages');
  var displayMsg = msg;
  if(hseqCurrentCat && HSEQ_CATEGORIES[hseqCurrentCat]){
    displayMsg = '<span style="font-size:10px;color:#868E96">['+HSEQ_CATEGORIES[hseqCurrentCat].label+']</span><br>'+escHtml(msg);
  }
  container.innerHTML += '<div class="msg user">'+displayMsg+'</div>';
  hseqHistory.push({role:'user',content:msg});

  document.getElementById('hseqTyping').style.display='block';
  container.scrollTop = container.scrollHeight;

  fetch(BASE+'/api/chat/hseq',{
    method:'POST',
    headers:{'Content-Type':'application/json'},
    body:JSON.stringify({query:msg,history:hseqHistory.slice(-10),category:hseqCurrentCat})
  })
  .then(function(r){return r.json()})
  .then(function(d){
    document.getElementById('hseqTyping').style.display='none';
    document.getElementById('hseqSendBtn').disabled=false;
    if(d.error){
      container.innerHTML+='<div class="msg assistant">❌ '+escHtml(d.error)+'</div>';
    } else {
      var content = d.content||'';
      hseqHistory.push({role:'assistant',content:content});
      var rendered = renderHseqMarkdown(content);
      // Add sources
      if(d.sources && d.sources.length){
        rendered += '<div class="source-ref">📚 Bronnen: '+d.sources.join(' | ')+'</div>';
      }
      container.innerHTML+='<div class="msg assistant">'+rendered+'</div>';
    }
    container.scrollTop=container.scrollHeight;
  })
  .catch(function(err){
    document.getElementById('hseqTyping').style.display='none';
    document.getElementById('hseqSendBtn').disabled=false;
    container.innerHTML+='<div class="msg assistant">❌ Netwerkfout: '+escHtml(err.message)+'</div>';
    container.scrollTop=container.scrollHeight;
  });
}

function clearHseqChat(){
  hseqHistory=[];
  document.getElementById('hseqMessages').innerHTML='<div class="msg assistant" style="background:#fff;border:1px solid #E9ECEF;box-shadow:0 1px 3px rgba(0,0,0,.06)"><div style="font-weight:600;margin-bottom:8px;color:#003366">🧠 HSEQ Advisor</div><div style="font-size:13px;line-height:1.6">Nieuw gesprek! Stel je HSEQ vraag of kies een categorie.</div></div>';
}

function exportHseqChat(){
  if(!hseqHistory.length){alert('Geen gesprek om te exporteren.');return}
  var text='HSEQ Advisor — Gespreksexport\\nDatum: '+new Date().toLocaleString('nl-NL')+'\\n\\n';
  hseqHistory.forEach(function(m){text+=(m.role==='user'?'👤 Jij: ':'🧠 Advisor: ')+m.content+'\\n\\n'});
  var blob=new Blob([text],{type:'text/plain;charset=utf-8'});
  var a=document.createElement('a');a.href=URL.createObjectURL(blob);
  a.download='hseq-advies-'+new Date().toISOString().slice(0,10)+'.txt';a.click();
}
</script>

""", page_title='HSEQ Advisor', active='advisor', BASE_PATH=BASE_PATH)


@app.route('/api/chat/hseq', methods=['POST'])
def chat_hseq():
    """HSEQ Advisor chat endpoint with RAG."""
    data = request.get_json()
    query = data.get('query', '')
    history = data.get('history', [])
    category = data.get('category', '')

    if not query:
        return jsonify({'error': 'Vraag is verplicht'}), 400

    # Build system prompt
    system = HSEQ_SYSTEM_PROMPT

    # Add category context
    if category:
        cat_contexts = {
            'brzo': '## Huidige Focus: BRZO/Seveso\nDe gebruiker stelt vragen over BRZO 2015, Seveso III, ARIE, veiligheidsrapportages, company emergency plans, effectafstanden, kwantitatieve risicoberekeningen (QRA).',
            'arbo': '## Huidige Focus: Arbowetgeving\nDe gebruiker stelt vragen over de Arbowet, Arbobesluit, RI&E, arbeidsomstandigheden, werkgeversplichten, preventiemedewerker, bedrijfsarts.',
            'gevaarlijk': '## Huidige Focus: Gevaarlijke Stoffen\nDe gebruiker stelt vragen over REACH, CLP/GHS, PGS-richtlijnen, veiligheidsinformatiebladen (SDS), classificatie, etikettering, opslag van gevaarlijke stoffen, MPL-waarden.',
            'milieu': '## Huidige Focus: Milieu & Omgeving\nDe gebruiker stelt vragen over de Omgevingswet, milieuvergunningen, emissies, lozingen, afvalstoffen, bodembescherming, MER, CO2-reductie.',
            'ongeval': '## Huidige Focus: Incidenten & Ongelukken\nDe gebruiker stelt vragen over MIR-meldplicht, ongevallenonderzoek, root cause analysis (RCA), TRIPOD, veiligheidscultuur, leren van incidenten.',
            'training': '## Huidige Focus: Training & Opleiding\nDe gebruiker stelt vragen over veiligheidstrainingen, toolbox talks, competentie-eisen, instructie en voorlichting, voorbehouden handelingen, VCA.'
        }
        if category in cat_contexts:
            system += '\n\n' + cat_contexts[category]

    # Always include SOP/Styleguide context
    sop_context = get_sop_context()
    if sop_context:
        system += '\n\n' + sop_context
    
    # RAG: search knowledge bank for specific documents
    rag_context, sources = get_rag_context(query, max_chars=6000)
    if rag_context:
        system += '\n\n## Relevante Documenten uit de HSEQ Kennisbank:\n' + rag_context
    if sources:
        system += '\n\nBronnen (vermeld deze in je antwoord): ' + ', '.join(sources)
    
    # Add topic context if provided (from service page click)
    topic = data.get('topic', '')
    if topic:
        system += f'\n\n## Specifiek Onderwerp: {topic}\nDe gebruiker klikte op dit onderwerp in het dashboard. Geef een gericht, professioneel antwoord met praktische stappen.'

    # Build messages
    messages = [{'role': 'system', 'content': system}]
    for msg in history[-10:]:
        if msg.get('role') in ('user', 'assistant') and msg.get('content'):
            messages.append({'role': msg['role'], 'content': msg['content']})
    messages.append({'role': 'user', 'content': query})

    try:
        response_text = ai_complete(messages)
    except Exception as e:
        response_text = f"⚠️ AI-assistent momenteel niet beschikbaar. Fout: {str(e)}"

    return jsonify({'content': response_text, 'query': query, 'sources': sources})


# ═══════════════════════════════════════════════════════════════════════════
# DIENSTEN (KWA-inspired service pages)
# ═══════════════════════════════════════════════════════════════════════════

SERVICES = {
    'arbo': {
        'title': 'Arbo & Veiligheid',
        'emoji': '👷',
        'subtitle': 'Arbowetgeving, RI&E, arbeidshygiëne en veiligheidsadvies',
        'description': 'Goede arbeidsomstandigheden en een veilige werkomgeving zijn essentieel voor een prettige werkplek. De wetgeving vereist een volledige en actuele RI&E als basis. Wij ondersteunen met onderzoek, metingen en advies op het gebied van ergonomie, gehoor, licht, klimaat, chemische stoffen en biologische agentia.',
        'capabilities': [
            ('📋', 'RI&E Opstellen', 'Risico-Inventarisatie & Evaluatie, van quickscan tot verdiepende RI&E met arbeidshygiënisch onderzoek'),
            ('🔍', 'Arbeidshygiëne', 'Onderzoek en metingen: geluid, trilling, stof, dampen, gevaarlijke stoffen, hitte, licht'),
            ('🦺', 'PBM Beleid', 'Advies over Persoonlijke Beschermingsmiddelen, selectie en gebruik'),
            ('🏗️', 'Bouwveiligheid', 'Veiligheidsplannen, V&G-coördinatie, UAV-GC compliance'),
            ('🏢', 'MVK / HVK', 'Veiligheidskundige op locatie, interim of projectmatig'),
            ('🤝', 'Veiligheidscultuur', 'Meten en verbeteren van veiligheidsgedrag en -cultuur'),
            ('📐', 'Ergonomie', 'Werkplekanalyse, tiladvies, beeldschermwerk, fysieke belasting'),
            ('📝', 'Arboverplichtingen', 'ISO 45001, VCA, Arbobesluit compliance en audits'),
        ],
        'advisor_category': 'arbo',
        'quick_questions': [
            'Welke PBM\'s zijn verplicht voor werk met gevaarlijke stoffen?',
            'Hoe vaak moet een RI&E worden geactualiseerd?',
            'Wat zijn de eisen voor geluidmeting op de werkvloer?',
            'Hoe zet ik een V&G-plan op voor een bouwproject?',
        ],
    },
    'brzo': {
        'title': 'BRZO / Seveso',
        'emoji': '🏭',
        'subtitle': 'BRZO 2015, Seveso III, ARIE en industriële veiligheid',
        'description': 'Bedrijven die vallen onder de BRZO-wetgeving hebben specifieke kennis en ervaring nodig. Van veiligheidsrapportages en Company Emergency Plans tot kwantitatieve risicoberekeningen en BRZO-werkgroepen. Wij ondersteunen bij alle aspecten van externe en procesveiligheid.',
        'capabilities': [
            ('📄', 'Veiligheidsrapport', 'Opstellen en actualiseren van het veiligheidsrapport (MID)'),
            ('📊', 'QRA', 'Kwantitatieve Risico Analyse en effectafstandberekeningen'),
            ('🚨', 'Emergency Plan', 'Company Emergency Plan (BHV / Ontruimingsplan op maat)'),
            ('📐', 'ARIE', 'Algemene Richtlijn Industriële Veiligheid implementatie en advies'),
            ('⛽', 'PGS-richtlijnen', 'Toepassing Publieke Gezondheid & Stoffen richtlijnen'),
            ('🔬', 'Procesveiligheid', 'HAZOP, LOPA, SIL-classificatie, veiligheidsfuncties'),
            ('👥', 'BRZO Werkgroep', 'Faciliteren en deelnemen aan regionale BRZO-werkgroepen'),
            ('🔄', 'MIR', 'Meldplicht Incidenten Gevaarlijke Stoffen — begeleiding bij melding'),
        ],
        'advisor_category': 'brzo',
        'quick_questions': [
            'Wanneer is mijn bedrijf BRZO-plichtig?',
            'Wat moet er in een veiligheidsrapport staan?',
            'Hoe bereken ik de effectafstand voor mijn inrichting?',
            'Wat is het verschil tussen BRZO en Seveso III?',
        ],
    },
    'milieu': {
        'title': 'Milieu & Omgeving',
        'emoji': '🌿',
        'subtitle': 'Omgevingswet, milieuvergunningen en duurzaamheid',
        'description': 'Ieder bedrijf beïnvloedt de leefomgeving. Om effecten te beperken is wet- en regelgeving opgesteld. Wij helpen bij het naleven van milieuwetgeving, het verkrijgen van vergunningen en het minimaliseren van milieubelasting door emissies, lozingen en afvalstoffen.',
        'capabilities': [
            ('📜', 'Omgevingswet', 'Advies en implementatie van de Omgevingswet en omgevingsvergunning'),
            ('💨', 'Luchtemissies', 'Emissieberekeningen, vergunningsaanvragen en monitoring'),
            ('💧', 'Water & Lozingen', 'Lozingsvergunningen, waterbeheer en hemelwater'),
            ('🗑️', 'Afvalstoffen', 'Afvalstoffenbeheer, NAUP, grondstoffenregistratie'),
            ('🌍', 'MER', 'Milieueffectrapportage en strategische MER'),
            ('🏭', 'BRZO Milieu', 'Milieubelasting bij BRZO-inrichtingen, effectafstanden'),
            ('📊', 'CO2 & Energietransitie', 'EU-ETS, CO2-reductie, energiebesparing en duurzaamheid'),
            ('🔍', 'Bodemonderzoek', 'Bodemkwaliteit, PFK, verontreiniging en sanering'),
        ],
        'advisor_category': 'milieu',
        'quick_questions': [
            'Welke vergunningen heb ik nodig voor mijn inrichting?',
            'Hoe rapporteer ik mijn emissies onder de Omgevingswet?',
            'Wat zijn de eisen voor lozingen op oppervlaktewater?',
            'Hoe bereken ik mijn CO2-voetafdruk?',
        ],
    },
    'kam': {
        'title': 'KAM Management',
        'emoji': '📋',
        'subtitle': 'Kwaliteit, Arbo, Milieu — managementsystemen en audits',
        'description': 'Wij ondersteunen bij bedrijfsdoelstellingen door in te zetten op goed functionerende processen, heldere taakverdeling, competente medewerkers en juiste middelen. Van compliance scans en audits tot het ontwerpen en implementeren van geïntegreerde managementsystemen.',
        'capabilities': [
            ('✅', 'ISO 9001', 'Kwaliteitsmanagementsysteem implementatie en certificering'),
            ('🛡️', 'ISO 45001', 'Arbomanagementsysteem opzetten en borgen'),
            ('🌿', 'ISO 14001', 'Milieumanagementsysteem en duurzaamheidsbeleid'),
            ('🔗', 'Geïntegreerd MMS', 'KAM-systeem dat Q, A en M samenbrengt in één systeem'),
            ('🔍', 'Audits & Scans', 'Interne audits, compliance scans en gap analyses'),
            ('📊', 'KPI Dashboard', 'KAM-prestaties meten, sturen en rapporteren'),
            ('📝', 'Documentatie', 'Procedures, werkinstructies en formulieren op orde'),
            ('🔄', 'Continu Verbeteren', 'PDCA-cyclus, verbetertrajecten en Lean Six Sigma'),
        ],
        'advisor_category': '',
        'quick_questions': [
            'Hoe start ik met ISO 45001 implementatie?',
            'Wat is het verschil tussen een interne audit en een certificeringsaudit?',
            'Hoe zet ik een effectief KAM-managementsysteem op?',
            "Welke KPI's moet ik meten voor veiligheid?",
        ],
    },
    'training': {
        'title': 'Training & Opleiding',
        'emoji': '🎓',
        'subtitle': 'Veiligheidstrainingen, toolbox talks en competentiebeheer',
        'description': 'Effectieve training en instructie is essentieel voor veilig werken. Van wettelijk verplichte certificeringen tot bedrijfsspecifieke toolbox talks. Wij helpen bij het opzetten van een trainingsbeleid, het ontwikkelen van materiaal en het borgen van competenties.',
        'capabilities': [
            ('🔧', 'Toolbox Talks', 'Korte interactieve veiligheidssessies op de werkvloer'),
            ('📚', 'Training Generator', 'Automatisch trainingen genereren uit procedures en richtlijnen'),
            ('🎓', 'VCA Training', 'Voorbereiding op VCA Basis en VCA VOL'),
            ('📝', 'Competentiebeheer', 'Register van voorbehouden handelingen en kwalificaties'),
            ('🎬', 'E-learning', 'Digitere leermodules met quiz en certificering'),
            ('📋', 'Instructiekaarten', 'Visuele werkinstructies voor taakgebonden risico\'s'),
            ('📊', 'Trainingsmatrix', 'Overzicht van verplichte trainingen per functie'),
            ('🔍', 'Effectmeting', 'Toetsen of trainingen daadwerkelijk gedrag veranderen'),
        ],
        'advisor_category': 'training',
        'quick_questions': [
            'Hoe vaak moeten medewerkers een veiligheidstraining volgen?',
            'Wat moet er in een toolbox talk staan?',
            'Wanneer is VCA-certificering verplicht?',
            'Hoe toets ik of een training effectief is?',
        ],
    },
    'energy': {
        'title': 'Energie & Proces',
        'emoji': '⚡',
        'subtitle': 'Energiebesparing, procesoptimalisatie en energietransitie',
        'description': 'Uw productieproces kent diverse levensfases: ontwerp, bouw, operationeel en transitie. Wij helpen bij het optimaliseren van procesefficiency en energie-efficiency, van procesanalyses en -metingen tot CO2-reductie en energietransitie strategieën.',
        'capabilities': [
            ('⚡', 'Energieaudit', 'Energiebesparingspotentieel in kaart brengen (EED verplicht)'),
            ('🏭', 'Procesanalyse', 'Procesefficiency, bottum analyses en optimalisatie'),
            ('🌡️', 'Warmte & Koude', 'Warmtenetwerken, warmtepompen, restwarmte benutting'),
            ('📊', 'EU-ETS', 'CO2-emissiehandel, monitoringsprotocollen en compliance'),
            ('🔄', 'Energietransitie', 'Roadmap naar CO2-reductie en duurzame energie'),
            ('🔧', 'Meettechniek', 'Procesmetingen, flow, temperatuur, druk, samenstelling'),
            ('📈', 'Performance', 'Operationele performance, OEE en proces KPI\'s'),
            ('📝', 'Subsidie & Regeling', 'DEI, SDE++, ISDE en andere energiemaatregelen'),
        ],
        'advisor_category': '',
    },
}


@app.route('/services/<service_id>')
def service_page(service_id):
    svc = SERVICES.get(service_id)
    if not svc:
        return page('<div class="empty-state"><div class="emoji">❌</div><h3>Dienst niet gevonden</h3></div>'), 404

    return page("""

<div style="margin-bottom:20px">
  <a href="{{BASE_PATH}}/" class="btn btn-outline btn-sm">← Dashboard</a>
</div>

<!-- Hero -->
<div class="card" style="background:linear-gradient(135deg,#003366,#005580);color:#fff;border:none">
  <div style="display:flex;align-items:center;gap:16px;margin-bottom:12px">
    <div style="width:56px;height:56px;border-radius:12px;background:rgba(255,255,255,.15);display:flex;align-items:center;justify-content:center;font-size:28px">{{svc['emoji']}}</div>
    <div>
      <h2 style="margin:0;color:#fff;font-size:20px">{{svc['title']}}</h2>
      <p style="margin:4px 0 0;font-size:12px;color:rgba(255,255,255,.7)">{{svc['subtitle']}}</p>
    </div>
  </div>
  <p style="font-size:13px;line-height:1.6;color:rgba(255,255,255,.9)">{{svc['description']}}</p>
</div>

<!-- Tool Grid: Elke capability is een actieve tool met actieknoppen -->
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;margin-bottom:24px">
  {% for cap in svc['capabilities'] %}
  <div class="card" style="border-left:4px solid {{svc.get('color','#003366')}};padding:0;overflow:hidden">
    <div style="padding:16px 16px 8px">
      <div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">
        <span style="font-size:28px">{{cap[0]}}</span>
        <h3 style="font-size:15px;color:#003366;margin:0;font-weight:600">{{cap[1]}}</h3>
      </div>
      <p style="font-size:12px;color:#868E96;line-height:1.5;margin:0">{{cap[2]}}</p>
    </div>
    <div style="padding:8px 16px 16px;display:flex;flex-wrap:wrap;gap:6px">
      <button onclick="openTool(this,'{{cap[1]|e}}','advies','{{svc.get("advisor_category","")|e}}')" data-label="💡 Advies" style="flex:1;min-width:80px;padding:10px 10px;border:1px solid #003366;border-radius:6px;background:#003366;color:#fff;font-size:12px;cursor:pointer;font-weight:600;-webkit-tap-highlight-color:transparent">💡 Advies</button>
      <button onclick="openTool(this,'{{cap[1]|e}}','procedure','{{svc.get("advisor_category","")|e}}')" data-label="📋 Procedure" style="flex:1;min-width:80px;padding:10px 10px;border:1px solid #4ECDC4;border-radius:6px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-weight:600;-webkit-tap-highlight-color:transparent">📋 Procedure</button>
      <button onclick="openTool(this,'{{cap[1]|e}}','checklist','{{svc.get("advisor_category","")|e}}')" data-label="✅ Checklist" style="flex:1;min-width:80px;padding:10px 10px;border:1px solid #FFB800;border-radius:6px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-weight:600;-webkit-tap-highlight-color:transparent">✅ Checklist</button>
      <button onclick="openTool(this,'{{cap[1]|e}}','rapport','{{svc.get("advisor_category","")|e}}')" data-label="📊 Rapport" style="flex:1;min-width:80px;padding:10px 10px;border:1px solid #E74C3C;border-radius:6px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-weight:600;-webkit-tap-highlight-color:transparent">📊 Rapport</button>
      <button onclick="openTool(this,'{{cap[1]|e}}','training','{{svc.get("advisor_category","")|e}}')" data-label="🎓 Training" style="flex:1;min-width:80px;padding:10px 10px;border:1px solid #9B59B6;border-radius:6px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-weight:600;-webkit-tap-highlight-color:transparent">🎓 Training</button>
    </div>
  </div>
  {% endfor %}
</div>

<!-- Generation Output Panel -->
<div id="gen-panel" class="card" style="display:none;border:2px solid #003366">
  <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
    <h3 style="margin:0;color:#003366" id="gen-title">🚀 Deliverable Generator</h3>
    <button onclick="document.getElementById('gen-panel').style.display='none'" style="background:none;border:none;font-size:18px;cursor:pointer;color:#868E96">✕</button>
  </div>
  <div id="gen-meta" style="font-size:12px;color:#868E96;margin-bottom:12px"></div>
  <div id="gen-output" style="background:#F8F9FA;border-radius:8px;padding:16px;max-height:600px;overflow-y:auto;font-size:13px;line-height:1.7;white-space:pre-wrap"></div>
  <div id="gen-sources" style="margin-top:12px;font-size:11px;color:#868E96"></div>
</div>

<!-- Snelvragen -->
{% if svc.get('quick_questions') %}
<div class="card" style="margin-top:16px">
  <h2 style="font-size:14px;margin-bottom:12px">💬 Snelvragen</h2>
  <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:8px">
    {% for q in svc['quick_questions'] %}
    <a href="{{BASE_PATH}}/advisor?cat={{svc.get('advisor_category','')|urlencode}}&q={{q|urlencode}}" class="card" style="text-decoration:none;display:block;padding:10px 14px;border-left:3px solid #4ECDC4;font-size:13px;color:#333;transition:all .2s" onmouseover="this.style.background='#F0F7FF'" onmouseout="this.style.background=''">{{q}} →</a>
    {% endfor %}
  </div>
</div>
{% endif %}

<!-- Advisor CTA -->
<div style="margin-top:16px;text-align:center">
  <a href="{{BASE_PATH}}/advisor?cat={{svc.get('advisor_category','')|urlencode}}" class="btn btn-primary" style="padding:12px 24px;font-size:14px">🧠 Open HSEQ Advisor — Stel je eigen vraag</a>
</div>

<script>
var genLoading = false;
function openTool(btn, topic, type, category) {
  // Visual feedback on clicked button
  if(btn){btn.style.opacity='0.5';btn.textContent='⏳...';setTimeout(function(){btn.style.opacity='1';btn.textContent=btn.dataset.label||btn.textContent;},15000);}

  if (genLoading) return;
  genLoading = true;
  var panel = document.getElementById('gen-panel');
  var output = document.getElementById('gen-output');
  var meta = document.getElementById('gen-meta');
  var title = document.getElementById('gen-title');
  var typeLabels = {advies:'💡 Advies', procedure:'📋 Procedure', checklist:'✅ Checklist', rapport:'📊 Rapport', training:'🎓 Training'};
  title.textContent = (typeLabels[type]||type) + ' — ' + topic;
  meta.textContent = 'Zoeken in 106 documenten (SOP, procedures, wetgeving)...';
  output.textContent = '⏳ Bezig met analyseren van de kennisbank... Dit kan 10-20 seconden duren.';
  output.style.color = '#868E96';
  panel.style.display = 'block';
  panel.scrollIntoView({behavior:'smooth'});
  fetch('{{BASE_PATH}}/api/generate', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({topic: topic, type: type, category: category})
  })
  .then(function(r) { return r.json(); })
  .then(function(data) {
    output.textContent = data.content || 'Geen resultaat';
    output.style.color = '#333';
    meta.textContent = 'Gegenereerd: ' + (data.timestamp||'') + ' | Type: ' + (data.type||'');
    if (data.sources && data.sources.length > 0) {
      document.getElementById('gen-sources').textContent = '📚 Bronnen: ' + data.sources.join(' | ');
    }
    genLoading = false;
  })
  .catch(function(err) {
    output.textContent = '❌ Fout: ' + err.message;
    output.style.color = '#E74C3C';
    genLoading = false;
  });
}
</script>

""", page_title=svc['title'], active=service_id, svc=svc, BASE_PATH=BASE_PATH)


# ═══════════════════════════════════════════════════════════════════════════

# ─── DELIVERABLE GENERATOR ────────────────────────────────────────────────

@app.route('/api/generate', methods=['POST'])
def generate_deliverable():
    """Generate a deliverable using SOP + knowledge bank context."""
    data = request.get_json()
    topic = data.get('topic', '')
    deliv_type = data.get('type', 'advies')
    category = data.get('category', '')

    if not topic:
        return jsonify({'error': 'Onderwerp is verplicht'}), 400

    system = """Jij bent de AI-HSEQ-adviseur van JvG Consultancy (Jorick van Gemert).
nJe produceert HSEQ deliverables op Arcadis/KWA-niveau voor BRZO-bedrijven.

n## Golden Standard
n- Feitelijk, beknopt, hyper-professioneel
n- Geen AI-cliche2s, geen "misschien"
n- Autoritair in je vakgebied
n- Verwijs naar wetgeving en normen
n- JvG Consultancy branding

n## Deliverable Types
n- advies: Gestructureerd advies met risicobenadering en actiepunten
n- procedure: Stap-voor-stap met verantwoordelijkheden en controlemomenten
n- checklist: Uitvoerbare checklist met inspectiepunten
n- rapport: Formeel rapport met executive summary en aanbevelingen
n- training: Training outline met leerdoelen, inhoud en evaluatie

n## Output
nProduceer als gestructureerde markdown met header, inhoud en bronvermelding."""

    sop = get_sop_context()
    if sop:
        system += '\n' + sop

    rag, sources = get_rag_context(topic, max_chars=8000)
    if rag:
        system += '\n\n## Relevante Documenten:\n' + rag
    if sources:
        system += '\n\nBronnen: ' + ', '.join(sources)

    cat_focus = {
        'arbo': 'Focus: Arbowet, RI&E, arbeidshygiene, PBM',
        'brzo': 'Focus: BRZO 2015, Seveso III, ARIE, QRA',
        'milieu': 'Focus: Omgevingswet, milieuvergunningen, emissies',
        'training': 'Focus: Veiligheidstrainingen, toolbox talks, VCA',
    }
    if category in cat_focus:
        system += f"\n\n## {cat_focus[category]}"

    prompts = {
        'advies': f"Schrijf een professioneel HSEQ-advies over: {topic}. Inclusief samenvatting, risicoanalyse, aanbevelingen (hoog/medium/laag) en actiepunten met tijdslijn.",
        'procedure': f"Schrijf een HSEQ-procedure voor: {topic}. Inclusief doel, verantwoordelijkheden, materialen, stapsgewijze uitvoering en controlemomenten.",
        'checklist': f"Maak een HSEQ-checklist voor: {topic}. Inclusief inspectiepunten, normen, goed/afkeur criteria en frequentie.",
        'rapport': f"Schrijf een HSEQ-rapport over: {topic}. Inclusief executive summary, methodologie, bevindingen en aanbevelingen.",
        'training': f"Ontwerp een training over: {topic}. Inclusief leerdoelen, doelgroep, duur, inhoud per module en evaluatie.",
    }
    gen_prompt = prompts.get(deliv_type, prompts['advies'])
    gen_prompt += "\n\nVergeet niet de bronvermelding uit de kennisbank."

    messages = [{'role': 'system', 'content': system}, {'role': 'user', 'content': gen_prompt}]

    try:
        response_text = ai_complete(messages)
    except Exception as e:
        response_text = f"Fout bij genereren: {str(e)}"

    return jsonify({
        'content': response_text,
        'topic': topic,
        'type': deliv_type,
        'sources': sources,
        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M')
    })

# API ENDPOINTS
# ═══════════════════════════════════════════════════════════════════════════
@app.route('/api/stats')
def api_stats():
    return jsonify(get_stats())


@app.route('/api/categories')
def api_categories():
    return jsonify(get_categories())


# ─── Main ───────────────────────────────────────────────────────────────────
if __name__ == '__main__':
    port = 5052
    for arg in sys.argv[1:]:
        if arg.startswith('--port'):
            val = arg.split('=', 1)[1] if '=' in arg else '5052'
            port = int(val)
            break
    init_db()
    print(f"HSEQ Intelligence Dashboard starting on http://0.0.0.0:{port}")
    app.run(host='0.0.0.0', port=port, debug=False)
