from flask import Blueprint, render_template, request, jsonify, redirect, flash
from modules.core.security import requires_admin_auth
from modules.core.audit import audit_log
import threading
from modules.core.audit import audit_log

from oci_genai_llm_graphrag_rerank_rfp import (
    search_chunks_for_invalidation,
    revoke_chunk_by_hash,
    get_chunk_metadata,
    add_manual_knowledge_entry,
    reload_all
)

admin_bp = Blueprint("admin", __name__)


# =========================
# ADMIN HOME (invalidate UI)
# =========================
@admin_bp.route("/")
@requires_admin_auth
def admin_home():
    return render_template("admin_menu.html")

@admin_bp.route("/invalidate")
@requires_admin_auth
def invalidate_page():
    return render_template(
        "invalidate.html",
        results=[],
        statement=""
    )

# =========================
# SEARCH CHUNKS
# =========================
@admin_bp.route("/search", methods=["POST"])
@requires_admin_auth
def search_for_invalidation():

    statement = request.form["statement"]

    docs = search_chunks_for_invalidation(statement)

    hashes = [d.metadata.get("chunk_hash") for d in docs if d.metadata.get("chunk_hash")]
    meta = get_chunk_metadata(hashes)

    results = []

    for d in docs:
        h = d.metadata.get("chunk_hash")
        m = meta.get(h, {})

        results.append({
            "chunk_hash": h,
            "source": d.metadata.get("source"),
            "text": d.page_content,
            "origin": m.get("origin"),
            "status": m.get("status")
        })

    return render_template(
        "invalidate.html",
        statement=statement,
        results=results
    )


# =========================
# REVOKE
# =========================
@admin_bp.route("/revoke", methods=["POST"])
@requires_admin_auth
def revoke_chunk_ui():

    data = request.get_json()

    chunk_hash = str(data["chunk_hash"])
    reason = str(data.get("reason", "Manual revoke"))
    audit_log("INVALIDATE", f"chunk_hash={chunk_hash}")

    print("chunk_hash", chunk_hash)
    print("reason", reason)

    revoke_chunk_by_hash(chunk_hash, reason)

    return {"status": "ok", "chunk_hash": chunk_hash}


# =========================
# ADD MANUAL KNOWLEDGE
# =========================
@admin_bp.route("/add-knowledge", methods=["POST"])
@requires_admin_auth
def add_manual_knowledge():

    data = request.get_json(force=True)

    chunk_hash = add_manual_knowledge_entry(
        text=data["text"],
        author="ADMIN",
        reason=data.get("reason"),
        source="MANUAL_INPUT",
        origin="MANUAL",
        also_update_graph=True
    )
    audit_log("ADD_KNOWLEDGE", f"chunk_hash={chunk_hash}")

    return jsonify({
        "status": "OK",
        "chunk_hash": chunk_hash
    })

# =========================
# UPDATE CHUNK
# =========================
@admin_bp.route("/update-chunk", methods=["POST"])
@requires_admin_auth
def update_chunk():

    data = request.get_json() or {}

    chunk_hash = str(data.get("chunk_hash", "")).strip()
    text = str(data.get("text", "")).strip()

    print("chunk_hash", chunk_hash)
    print("text", text)

    if not chunk_hash:
        return {"status": "error", "message": "missing hash"}, 400

    reason = str(data.get("reason", "Manual change"))

    revoke_chunk_by_hash(chunk_hash, reason=reason)
    chunk_hash = add_manual_knowledge_entry(
        text=text,
        author="ADMIN",
        reason=reason,
        source="MANUAL_INPUT",
        origin="MANUAL",
        also_update_graph=True
    )
    audit_log("UPDATE CHUNK", f"chunk_hash={chunk_hash}")

    return jsonify({
        "status": "OK",
        "chunk_hash": chunk_hash
    })

@admin_bp.route("/reboot", methods=["POST"])
@requires_admin_auth
def reboot_service():
    # roda em background pra não travar request
    threading.Thread(target=reload_all, daemon=True).start()

    return jsonify({
        "status": "ok",
        "message": "Knowledge reload started"
    })