#!/usr/bin/env python3
"""
Kas Engine v3 — Native PDF analyse via Gemini met paginabereiken.
Splits grote PDF's in stukken van max 50 pagina's, analyseer elk stuk,
en syntheseer tot één eindrapport.
"""
import json, sys, os, requests, base64, time
import sqlite3, fitz
from datetime import datetime

DB_PATH = os.path.join(os.path.dirname(__file__), 'hseq_kennisbank.db')
GEMINI_API_KEY = os.environ.get('GEMINI_API_KEY')
GEMINI_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent'
MAX_PAGES_PER_CHUNK = 50

file_paths = json.loads(sys.argv[1])
context = sys.argv[2] if len(sys.argv) > 2 else ''
language = sys.argv[3] if len(sys.argv) > 3 else 'NL'
analysis_id = int(sys.argv[4]) if len(sys.argv) > 4 else 0


def update_db(status, result_text=None, error_msg=None):
    conn = sqlite3.connect(DB_PATH)
    c = conn.cursor()
    if error_msg:
        c.execute("UPDATE scanner_analyses SET status=?, error_msg=? WHERE id=?",
                  (status, error_msg, analysis_id))
    elif result_text:
        c.execute("UPDATE scanner_analyses SET status=?, result_json=?, completed_at=? WHERE id=?",
                  (status, json.dumps({'text': result_text}), datetime.now().isoformat(), analysis_id))
    else:
        c.execute("UPDATE scanner_analyses SET status=? WHERE id=?", (status, analysis_id))
    conn.commit()
    conn.close()


def gemini_call(prompt, pdf_base64, max_retries=3):
    """Enkele Gemini API call met retry."""
    payload = {
        'contents': [{
            'parts': [
                {'text': prompt},
                {'inline_data': {'mime_type': 'application/pdf', 'data': pdf_base64}}
            ]
        }],
        'generationConfig': {
            'temperature': 0.3,
            'maxOutputTokens': 16384
        }
    }

    for attempt in range(max_retries):
        try:
            resp = requests.post(
                f'{GEMINI_URL}?key={GEMINI_API_KEY}',
                json=payload, timeout=300
            )
            if resp.status_code == 429:
                wait = 30 * (attempt + 1)
                print(f"  Rate limited, wacht {wait}s (poging {attempt+1})...")
                time.sleep(wait)
                continue

            if resp.status_code == 400:
                error_detail = resp.json()
                msg = error_detail.get('error', {}).get('message', str(error_detail))[:300]
                return None, f"Gemini 400: {msg}"

            resp.raise_for_status()
            result = resp.json()

            if 'candidates' in result:
                return result['candidates'][0]['content']['parts'][0]['text'], None
            else:
                return None, f"Gemini antwoord onverwacht: {str(result)[:300]}"

        except requests.exceptions.Timeout:
            return None, "Gemini time-out (5 min)"
        except Exception as e:
            if attempt < max_retries - 1:
                time.sleep(10)
                continue
            return None, f"Gemini fout: {str(e)[:300]}"

    return None, f"Gemini na {max_retries} pogingen niet beschikbaar"


def split_pdf(filepath, max_pages=MAX_PAGES_PER_CHUNK):
    """Splits PDF in stukken van max_pages pagina's. Retourneert lijst van (chunk_pdf_path, page_range_str)."""
    doc = fitz.open(filepath)
    total = len(doc)
    chunks = []

    for start in range(0, total, max_pages):
        end = min(start + max_pages - 1, total - 1)
        chunk_doc = fitz.open()
        chunk_doc.insert_pdf(doc, from_page=start, to_page=end)
        chunk_path = f'/tmp/scan_chunk_{analysis_id}_{start}.pdf'
        chunk_doc.save(chunk_path)
        chunk_doc.close()
        chunks.append((chunk_path, f'pagina {start+1}-{end+1}'))

    doc.close()
    return chunks


def main():
    if not file_paths:
        update_db('error', error_msg='Geen bestanden ontvangen')
        return

    filepath, filename = file_paths[0]

    if not os.path.isfile(filepath):
        update_db('error', error_msg=f'Bestand niet gevonden: {filename}')
        return

    if not GEMINI_API_KEY:
        update_db('error', error_msg='GEMINI_API_KEY niet geconfigureerd')
        return

    lang_label = 'Nederlands' if language == 'NL' else 'English'

    # Stap 1: PDF splitsen in chunks
    print(f"Splitsen {filename}...")
    chunks = split_pdf(filepath)
    total = len(chunks)
    print(f"{total} chunks van max {MAX_PAGES_PER_CHUNK} pagina's")

    # Stap 2: Elk chunk analyseren
    chunk_analyses = []
    for i, (chunk_path, page_range) in enumerate(chunks):
        print(f"Analyse chunk {i+1}/{total} ({page_range})...")

        with open(chunk_path, 'rb') as f:
            pdf_b64 = base64.b64encode(f.read()).decode()
        print(f"  Base64: {len(pdf_b64)/1024/1024:.1f} MB")

        chunk_prompt = (
            f"Dit is DEEL {i+1}/{total} van document '{filename}' ({page_range}).\n\n"
            "Analyseer dit deel gedetailleerd:\n"
            "- Welke hoofdstukken/secties komen aan bod?\n"
            "- Welke HSEQ-aspecten (veiligheid, compliance, risico, milieu, kwaliteit)?\n"
            "- Specifieke eisen, normen, waarden, scenario's?\n"
            "- Tabellen, formules, berekeningen?\n"
            "- Actiepunten of verplichtingen?\n\n"
            "Wees feitelijk en gedetailleerd. Citeer specifieke waarden en paragrafen."
        )

        result, error = gemini_call(chunk_prompt, pdf_b64)

        # Cleanup chunk file
        try:
            os.remove(chunk_path)
        except:
            pass

        if error:
            update_db('error', error_msg=f"Chunk {i+1} ({page_range}): {error}")
            print(f"  FOUT: {error}")
            return

        chunk_analyses.append(f"=== DEEL {i+1}/{total} ({page_range}) ===\n{result}")
        print(f"  OK: {len(result)} tekens")

    # Stap 3: Synthese tot eindrapport
    print("Synthese...")
    all_text = '\n\n'.join(chunk_analyses)

    synthese_prompt = (
        f"Je hebt {total} delen van document '{filename}' geanalyseerd.\n"
        f"Hier zijn de deelanalyses:\n\n{all_text}\n\n"
        "Maak nu EEN samenvoegend eindrapport:\n\n"
        "## 1. Leeswijzer\nDocument, scope, doelgroep, wettelijk kader.\n\n"
        "## 2. Executive Summary\nKernboodschap in max 250 woorden.\n\n"
        "## 3. Documentstructuur & Kerninhoud\nAlle hoofdstukken met bevindingen.\n\n"
        "## 4. HSEQ Highlights Matrix\nMinimaal 10 rijen:\n"
        "| Thema | Risico | Compliance-eis | Actiepunt | Prioriteit |\n\n"
        "## 5. Normen, Waarden & Scenario's\n\n"
        "## 6. Synergieen & Hiaten\n\n"
        "## 7. Actielijst voor Inrichtinghouder\nGenummerd, met prioriteit.\n\n"
        "Gebruik ALLE deelanalyses. Specifiek met hoofdstuk/paragraaf verwijzingen. "
        "HSEQ-terminologie. Feitelijk. Geen AI-cliches."
    )

    final_result, error = gemini_call(synthese_prompt, "")
    if error:
        # Fallback: geef de ruwe deelanalyses
        final_result = all_text

    update_db('completed', result_text=final_result)
    print(f"Analyse {analysis_id} voltooid: {len(final_result)} tekens")


if __name__ == '__main__':
    main()
