#!/usr/bin/env python3
"""
================================================================================
ALFRED LINUX v7.5.3 — AUTHORIZED KING JESUS VERSION (PEREZ EDITION) SCRIPTURE STUDIO
Complete 94-Book Sacred Canon • 39,482 Verses • Offline Concordance & Audio Suite
All 94 Books: Old Testament (39), New Testament (27), Apocrypha (14), Enochian (14)
================================================================================
"""

import os
import sys
import csv
import json
import shutil
import re
import subprocess
import urllib.request
import urllib.error

# Force XWayland for rock-solid sovereign desktop rendering on KDE Plasma
uid = os.getuid() if hasattr(os, "getuid") else 1000
if "XDG_RUNTIME_DIR" not in os.environ:
    os.environ["XDG_RUNTIME_DIR"] = f"/run/user/{uid}"
if "WAYLAND_DISPLAY" not in os.environ and os.path.exists(f"/run/user/{uid}/wayland-0"):
    os.environ["WAYLAND_DISPLAY"] = "wayland-0"
if "XAUTHORITY" not in os.environ:
    import glob
    xauth_files = glob.glob(f"/run/user/{uid}/xauth_*")
    if xauth_files:
        os.environ["XAUTHORITY"] = xauth_files[0]
if os.environ.get("WAYLAND_DISPLAY"):
    os.environ.setdefault("QT_QPA_PLATFORM", "wayland;xcb")
elif os.environ.get("DISPLAY"):
    os.environ.setdefault("QT_QPA_PLATFORM", "xcb")

from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt6.QtGui import QFont, QColor, QTextCursor, QTextCharFormat, QKeySequence, QShortcut
from PyQt6.QtWidgets import (
    QApplication,
    QMainWindow,
    QWidget,
    QVBoxLayout,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QTextBrowser,
    QTextEdit,
    QComboBox,
    QFrame,
    QSplitter,
    QTabWidget,
    QTableWidget,
    QTableWidgetItem,
    QHeaderView,
    QListWidget,
    QListWidgetItem,
    QProgressBar,
    QMessageBox,
    QToolTip,
)

EDITION_TITLE = "Authorized King Jesus Version (Perez Edition)"
DATA_DIR = "/usr/share/alfred/bible"
BOOKS_TSV = os.path.join(DATA_DIR, "akjv-books.tsv")
BIBLE_TSV = os.path.join(DATA_DIR, "akjv-bible.tsv")
PDF_PATH = os.path.join(DATA_DIR, "akjv-perez-edition.pdf")

# Fallback paths if /usr/share/alfred/bible is not yet populated
FALLBACK_DATA_DIR = "/opt/bible"

TESTAMENT_LABELS = {
    "ALL": "All 94 Books (Complete Perez Canon)",
    "OT": "Old Testament (39 Books • Law, History, Wisdom, Prophets)",
    "NT": "New Testament (27 Books • Gospels, Epistles, Revelation)",
    "AP": "Apocrypha (14 Books • 1611 Deuterocanon)",
    "EN": "Enochian & Ancient (14 Books • Enoch, Jubilees, Hermas)",
}

FLAGSHIP_PASSAGES = [
    ("Psalm 91", "Psalms", 91, "The Secret Place of the Most High — Shield & Buckler"),
    ("Genesis 1", "Genesis", 1, "The Creation of Heaven and Earth — In the Beginning"),
    ("John 1", "John", 1, "The Word Made Flesh — The Light Shineth in Darkness"),
    ("1 Enoch 1", "1 Enoch (Book of Enoch)", 1, "The Prophecy of the Holy Great One (Jude 1:14-15)"),
    ("Ephesians 6", "Ephesians", 6, "The Whole Armour of God — Spiritual Warfare"),
    ("Matthew 5", "Matthew", 5, "The Beatitudes & Light of the World"),
    ("Daniel 5", "Daniel", 5, "The Writing on the Wall: MENE MENE TEKEL UPHARSIN (PERES / Perez)"),
    ("Ruth 4", "Ruth", 4, "The Covenant Blessing & Royal Lineage of Perez"),
    ("Matthew 1", "Matthew", 1, "The Genealogy of Jesus Christ, Son of David, Son of Perez"),
    ("Revelation 21", "Revelation", 21, "The New Heaven and New Earth — All Things New"),
    ("Jubilees 1", "Jubilees", 1, "The Revelation to Moses on Mount Sinai — The Jubilees"),
    ("Shepherd of Hermas 1", "Shepherd of Hermas", 1, "The Vision of the Tower & The Angel of Repentance"),
]

SOVEREIGN_STYLESHEET = """
QMainWindow, QWidget {
    background-color: #0A0B0E;
    color: #F4ECD8;
    font-family: 'Liberation Sans', 'Segoe UI', 'DejaVu Sans', sans-serif;
    font-size: 13px;
}
QFrame#HeaderBanner {
    background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
        stop:0 #0F0E0B, stop:0.35 #1F190D, stop:0.7 #261F10, stop:1 #0F0E0B);
    border: 1px solid #D4AF37;
    border-radius: 8px;
    padding: 6px 12px;
}
QFrame#CardPanel {
    background-color: #11131A;
    border: 1px solid #332B1A;
    border-radius: 7px;
    padding: 6px;
}
QLabel#TitleLabel {
    color: #FFD700;
    font-size: 19px;
    font-weight: bold;
    letter-spacing: 0.8px;
    font-family: 'Georgia', 'Liberation Serif', serif;
}
QLabel#SubtitleLabel {
    color: #C8A951;
    font-size: 11px;
}
QLabel#SectionLabel {
    color: #E5C158;
    font-weight: bold;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
}
QLabel#PassageHeaderTitle {
    color: #FFD700;
    font-size: 18px;
    font-weight: bold;
    font-family: 'Georgia', 'Liberation Serif', serif;
}
QLabel#PassageMetaLabel {
    color: #A09882;
    font-size: 11px;
}
QLineEdit {
    background-color: #141722;
    color: #FFF2CC;
    border: 1px solid #8A7028;
    border-radius: 5px;
    padding: 6px 10px;
    font-size: 13px;
}
QLineEdit:focus {
    border: 1px solid #FFD700;
    background-color: #181C2A;
}
QComboBox {
    background-color: #141722;
    color: #FFD700;
    border: 1px solid #8A7028;
    border-radius: 5px;
    padding: 5px 8px;
    font-weight: bold;
    font-size: 12px;
    min-height: 24px;
}
QComboBox:hover {
    border: 1px solid #FFD700;
    background-color: #191E2E;
}
QComboBox QAbstractItemView {
    background-color: #10121A;
    color: #F4ECD8;
    selection-background-color: #D4AF37;
    selection-color: #0A0B0E;
    border: 1px solid #D4AF37;
    padding: 4px;
}
QTextBrowser, QTextEdit {
    background-color: #0B0C10;
    color: #F7EFE1;
    border: 1px solid #2F2718;
    border-radius: 6px;
    padding: 16px 20px;
    selection-background-color: #D4AF37;
    selection-color: #0A0B0E;
}
QPushButton {
    background-color: #181B26;
    color: #E2CCA0;
    border: 1px solid #755E22;
    border-radius: 5px;
    padding: 6px 12px;
    font-weight: bold;
    font-size: 12px;
}
QPushButton:hover {
    background-color: #262112;
    border: 1px solid #FFD700;
    color: #FFD700;
}
QPushButton:disabled {
    background-color: #101116;
    color: #555044;
    border: 1px solid #22201A;
}
QPushButton#GoldBtn {
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
        stop:0 #E5C158, stop:1 #A87A0B);
    color: #0A0B0E;
    border: 1px solid #FFD700;
    font-weight: bold;
}
QPushButton#GoldBtn:hover {
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
        stop:0 #FFE082, stop:1 #C89410);
    color: #000000;
}
QPushButton#StopBtn {
    background-color: #2D1418;
    color: #FFA5A5;
    border: 1px solid #8C2E38;
}
QPushButton#StopBtn:hover {
    background-color: #421B21;
    border: 1px solid #FF5252;
    color: #FFFFFF;
}
QPushButton#SmallNavBtn {
    padding: 5px 10px;
    min-width: 45px;
    font-weight: bold;
}
QTabWidget::pane {
    border: 1px solid #332B1A;
    background-color: #0D0F16;
    border-radius: 6px;
}
QTabBar::tab {
    background-color: #12141D;
    color: #B0A690;
    border: 1px solid #2B2416;
    padding: 7px 12px;
    margin-right: 3px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    font-weight: bold;
    font-size: 11px;
}
QTabBar::tab:selected {
    background-color: #1F1B12;
    color: #FFD700;
    border-bottom: 2px solid #FFD700;
}
QTabBar::tab:hover {
    color: #FFD700;
    background-color: #181714;
}
QTableWidget, QListWidget {
    background-color: #0C0E14;
    color: #EFE6D5;
    border: 1px solid #2A2315;
    border-radius: 5px;
    gridline-color: #1F1B14;
    selection-background-color: #382F19;
    selection-color: #FFD700;
}
QHeaderView::section {
    background-color: #141722;
    color: #FFD700;
    padding: 5px;
    border: 1px solid #2A2315;
    font-weight: bold;
    font-size: 11px;
}
QScrollBar:vertical {
    background-color: #0A0B0E;
    width: 12px;
    border-radius: 6px;
}
QScrollBar::handle:vertical {
    background-color: #2F2A1C;
    border-radius: 5px;
    min-height: 25px;
}
QScrollBar::handle:vertical:hover {
    background-color: #D4AF37;
}
QProgressBar {
    border: 1px solid #8A7028;
    border-radius: 4px;
    background-color: #10121A;
    text-align: center;
    color: #FFD700;
    font-weight: bold;
    font-size: 11px;
    max-height: 14px;
}
QProgressBar::chunk {
    background-color: #B8860B;
}
"""

def clean_branding(text: str) -> str:
    """Ensure divine titles and edition branding are honored consistently."""
    cleaned = text
    for term in ("King James Version", "King James", "KJV"):
        cleaned = cleaned.replace(term, EDITION_TITLE)
    return cleaned

def compute_gematria(text: str) -> dict:
    """Compute English Ordinal, Standard Hebrew/Greek-style, and Symbolic Gematria."""
    clean = re.sub(r'[^A-Za-z]', '', text).upper()
    ordinal = sum((ord(c) - 64) for c in clean)
    standard = sum((ord(c) - 64) * 6 for c in clean) # Sumerian 6-base
    word_count = len(text.split())
    char_count = len(clean)
    return {
        "ordinal": ordinal,
        "sumerian": standard,
        "word_count": word_count,
        "char_count": char_count,
    }

class AudioNarrationWorker(QThread):
    finished_signal = pyqtSignal()
    status_signal = pyqtSignal(str)

    def __init__(self, passage_text: str):
        super().__init__()
        self.passage_text = passage_text
        self._proc = None
        self._stopped = False

    def run(self):
        if not self.passage_text:
            self.finished_signal.emit()
            return

        # Prepare natural spoken text: remove verse brackets [1], headers, etc.
        lines = []
        for line in self.passage_text.splitlines():
            line = line.strip()
            if not line or line.startswith("===") or line.startswith("[Authorized"):
                continue
            cleaned = re.sub(r'\[\d+\]', '', line)
            cleaned = re.sub(r'^\d+:\d+\s*', '', cleaned)
            lines.append(cleaned.strip())

        spoken = " ".join(lines)
        spoken = spoken[:8000] # limit length per single reading pass

        try:
            # 1. Try espeak-ng (installed on Alfred Datacenter & Workstation)
            if shutil.which("espeak-ng"):
                self._proc = subprocess.Popen(
                    ["espeak-ng", "-v", "en-us", "-s", "145", "-p", "48", spoken],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                )
                self._proc.wait()
            # 2. Try alfred-oracle-speak
            elif os.path.exists("/usr/local/bin/alfred-oracle-speak"):
                self._proc = subprocess.Popen(
                    ["/usr/local/bin/alfred-oracle-speak", spoken],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                )
                self._proc.wait()
            # 3. Try spd-say
            elif shutil.which("spd-say"):
                self._proc = subprocess.Popen(
                    ["spd-say", "-r", "-10", spoken],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                )
                self._proc.wait()
        except Exception as e:
            self.status_signal.emit(f"Audio playback error: {e}")
        finally:
            self.finished_signal.emit()

    def stop(self):
        self._stopped = True
        if self._proc and self._proc.poll() is None:
            try:
                self._proc.terminate()
                self._proc.kill()
            except Exception:
                pass
        for p in ("espeak-ng", "espeak", "spd-say", "aplay", "pw-play", "paplay"):
            subprocess.run(["pkill", "-f", p], capture_output=True)


class BibleStudioWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(f"ALFRED OS — {EDITION_TITLE} Scripture & Concordance Studio (94 Books)")
        self.resize(1280, 840)
        self.setMinimumSize(1024, 680)
        self.setStyleSheet(SOVEREIGN_STYLESHEET)

        # State data
        self.books = []            # list of dicts from akjv-books.tsv
        self.books_by_name = {}    # name -> dict
        self.bible_data = {}       # book_name -> {chapter: {verse: text}}
        self.current_book = None
        self.current_chapter = 1
        self.current_verses = {}
        self.font_size = 16
        self.audio_worker = None

        # Load datasets
        self._load_datasets()

        # Build UI
        self._build_ui()

        # Default initial view: Psalm 91
        self.select_book_and_chapter("Psalms", 91)

    def _load_datasets(self):
        """Load akjv-books.tsv and akjv-bible.tsv into memory."""
        # Locate files
        books_file = BOOKS_TSV if os.path.exists(BOOKS_TSV) else os.path.join(FALLBACK_DATA_DIR, "akjv-books.tsv")
        bible_file = BIBLE_TSV if os.path.exists(BIBLE_TSV) else os.path.join(FALLBACK_DATA_DIR, "akjv-bible.tsv")

        # Load Books
        if os.path.exists(books_file):
            try:
                with open(books_file, "r", encoding="utf-8") as f:
                    reader = csv.DictReader(f, delimiter="\t")
                    for r in reader:
                        b = {
                            "num": int(r["book_number"]),
                            "name": r["book_name"],
                            "abbr": r["abbreviation"],
                            "testament": r["testament"],
                            "category": r["category"],
                            "chapters": int(r["total_chapters"]),
                            "canon": r.get("canon_source", "Sacred Canon"),
                            "status": r.get("status", "Standard"),
                            "perez": r.get("perez_references", ""),
                        }
                        self.books.append(b)
                        self.books_by_name[b["name"]] = b
            except Exception as e:
                print(f"Error loading books TSV: {e}")

        # Load Verses
        if os.path.exists(bible_file):
            try:
                with open(bible_file, "r", encoding="utf-8") as f:
                    reader = csv.DictReader(f, delimiter="\t")
                    for r in reader:
                        b = r["book_name"]
                        c = int(r["chapter"])
                        v = int(r["verse"])
                        txt = r["text_akjv"]
                        if b not in self.bible_data:
                            self.bible_data[b] = {}
                        if c not in self.bible_data[b]:
                            self.bible_data[b][c] = {}
                        self.bible_data[b][c][v] = txt
            except Exception as e:
                print(f"Error loading bible TSV: {e}")

    def _build_ui(self):
        central = QWidget()
        self.setCentralWidget(central)
        root = QVBoxLayout(central)
        root.setContentsMargins(12, 10, 12, 10)
        root.setSpacing(8)

        # ----------------------------------------------------
        # TOP HEADER BANNER
        # ----------------------------------------------------
        header = QFrame()
        header.setObjectName("HeaderBanner")
        h_layout = QHBoxLayout(header)
        h_layout.setContentsMargins(12, 6, 12, 6)

        title_box = QVBoxLayout()
        title_box.setSpacing(2)
        lbl_title = QLabel(f"📜 {EDITION_TITLE.upper()}")
        lbl_title.setObjectName("TitleLabel")
        lbl_sub = QLabel("Complete 94-Book Sacred Canon • 39,482 Verses • Old Testament (39) • New Testament (27) • Apocrypha (14) • Enochian & Ancient (14)")
        lbl_sub.setObjectName("SubtitleLabel")
        title_box.addWidget(lbl_title)
        title_box.addWidget(lbl_sub)
        h_layout.addLayout(title_box)
        h_layout.addStretch()

        # Audio Narration & PDF Buttons
        self.btn_audio = QPushButton("🔊 Read Chapter")
        self.btn_audio.setObjectName("GoldBtn")
        self.btn_audio.setToolTip("Read aloud using Alfred Text-to-Speech")
        self.btn_audio.clicked.connect(self.start_reading_aloud)
        h_layout.addWidget(self.btn_audio)

        self.btn_stop_audio = QPushButton("⏹ Stop")
        self.btn_stop_audio.setObjectName("StopBtn")
        self.btn_stop_audio.setEnabled(False)
        self.btn_stop_audio.clicked.connect(self.stop_reading_aloud)
        h_layout.addWidget(self.btn_stop_audio)

        btn_pdf = QPushButton("📜 Open 94-Book PDF")
        btn_pdf.setToolTip("Open full Authorized King Jesus Version (Perez Edition) 94-Book PDF")
        btn_pdf.clicked.connect(self.open_pdf)
        h_layout.addWidget(btn_pdf)
        h_layout.addSpacing(440)

        root.addWidget(header)

        # ----------------------------------------------------
        # NAVIGATION & SEARCH CONTROLS (Row 1 & 2)
        # ----------------------------------------------------
        nav_card = QFrame()
        nav_card.setObjectName("CardPanel")
        nav_vbox = QVBoxLayout(nav_card)
        nav_vbox.setContentsMargins(8, 6, 8, 6)
        nav_vbox.setSpacing(6)

        # Row 1: Testament, Book, Chapter, Prev/Next, Flagship Jumps
        r1 = QHBoxLayout()
        r1.setSpacing(8)

        lbl_test = QLabel("TESTAMENT:")
        lbl_test.setObjectName("SectionLabel")
        r1.addWidget(lbl_test)

        self.combo_testament = QComboBox()
        self.combo_testament.addItem("All 94 Books (Complete Canon)", "ALL")
        self.combo_testament.addItem("Old Testament (39 Books)", "OT")
        self.combo_testament.addItem("New Testament (27 Books)", "NT")
        self.combo_testament.addItem("Apocrypha (14 Books)", "AP")
        self.combo_testament.addItem("Enochian & Ancient (14 Books)", "EN")
        self.combo_testament.currentIndexChanged.connect(self._on_testament_changed)
        r1.addWidget(self.combo_testament)

        lbl_book = QLabel("BOOK:")
        lbl_book.setObjectName("SectionLabel")
        r1.addWidget(lbl_book)

        self.combo_book = QComboBox()
        self.combo_book.setMinimumWidth(220)
        self.combo_book.currentIndexChanged.connect(self._on_book_changed)
        r1.addWidget(self.combo_book)

        lbl_chap = QLabel("CHAPTER:")
        lbl_chap.setObjectName("SectionLabel")
        r1.addWidget(lbl_chap)

        self.combo_chapter = QComboBox()
        self.combo_chapter.setMinimumWidth(125)
        self.combo_chapter.currentIndexChanged.connect(self._on_chapter_changed)
        r1.addWidget(self.combo_chapter)

        lbl_verse = QLabel("VERSE:")
        lbl_verse.setObjectName("SectionLabel")
        r1.addWidget(lbl_verse)

        self.combo_verse = QComboBox()
        self.combo_verse.setMinimumWidth(100)
        self.combo_verse.currentIndexChanged.connect(self._on_verse_changed)
        r1.addWidget(self.combo_verse)

        self.btn_prev = QPushButton("◀ Prev")
        self.btn_prev.setObjectName("SmallNavBtn")
        self.btn_prev.clicked.connect(self.prev_chapter)
        r1.addWidget(self.btn_prev)

        self.btn_next = QPushButton("Next ▶")
        self.btn_next.setObjectName("SmallNavBtn")
        self.btn_next.clicked.connect(self.next_chapter)
        r1.addWidget(self.btn_next)

        r1.addSpacing(12)

        lbl_flagship = QLabel("FLAGSHIP:")
        lbl_flagship.setObjectName("SectionLabel")
        r1.addWidget(lbl_flagship)

        self.combo_flagship = QComboBox()
        self.combo_flagship.setMinimumWidth(210)
        self.combo_flagship.addItem("⚡ Jump to Flagship Passage...")
        for title, b_name, ch, desc in FLAGSHIP_PASSAGES:
            self.combo_flagship.addItem(f"{title} — {desc}", (b_name, ch))
        self.combo_flagship.currentIndexChanged.connect(self._on_flagship_selected)
        r1.addWidget(self.combo_flagship)

        r1.addStretch()
        nav_vbox.addLayout(r1)

        # Row 2: Search Scripture Bar & Font Adjusters
        r2 = QHBoxLayout()
        r2.setSpacing(8)

        lbl_search = QLabel("SEARCH SCRIPTURE:")
        lbl_search.setObjectName("SectionLabel")
        r2.addWidget(lbl_search)

        self.input_search = QLineEdit()
        self.input_search.setPlaceholderText("Search 39,482 verses by keyword or reference (e.g. Perez, Melchizedek, Light, 1 Enoch 1:9, John 3:16)...")
        self.input_search.returnPressed.connect(self.perform_search)
        r2.addWidget(self.input_search)

        btn_search = QPushButton("🔎 Search All 94 Books")
        btn_search.setObjectName("GoldBtn")
        btn_search.clicked.connect(self.perform_search)
        r2.addWidget(btn_search)

        btn_clear = QPushButton("✅– Clear")
        btn_clear.clicked.connect(self.clear_search)
        r2.addWidget(btn_clear)

        r2.addSpacing(16)

        lbl_zoom = QLabel("FONT:")
        lbl_zoom.setObjectName("SectionLabel")
        r2.addWidget(lbl_zoom)

        btn_font_dec = QPushButton("A-")
        btn_font_dec.setObjectName("SmallNavBtn")
        btn_font_dec.clicked.connect(lambda: self.adjust_font(-2))
        r2.addWidget(btn_font_dec)

        btn_font_inc = QPushButton("A+")
        btn_font_inc.setObjectName("SmallNavBtn")
        btn_font_inc.clicked.connect(lambda: self.adjust_font(2))
        r2.addWidget(btn_font_inc)

        btn_copy = QPushButton("📋 Copy Chapter")
        btn_copy.clicked.connect(self.copy_current_chapter)
        r2.addWidget(btn_copy)

        nav_vbox.addLayout(r2)
        root.addWidget(nav_card)

        # ----------------------------------------------------
        # MAIN SPLITTER (Left: Scripture View, Right: Study Suite)
        # ----------------------------------------------------
        splitter = QSplitter(Qt.Orientation.Horizontal)

        # LEFT PANEL: Scripture Text View
        left_widget = QWidget()
        left_layout = QVBoxLayout(left_widget)
        left_layout.setContentsMargins(0, 0, 0, 0)
        left_layout.setSpacing(6)

        # Scripture View Header
        self.passage_header_frame = QFrame()
        self.passage_header_frame.setObjectName("CardPanel")
        ph_layout = QVBoxLayout(self.passage_header_frame)
        ph_layout.setContentsMargins(12, 8, 12, 8)
        ph_layout.setSpacing(2)

        self.lbl_passage_title = QLabel("PSALM 91")
        self.lbl_passage_title.setObjectName("PassageHeaderTitle")
        self.lbl_passage_meta = QLabel("OLD TESTAMENT • WISDOM • 150 TOTAL CHAPTERS • KJV 1611")
        self.lbl_passage_meta.setObjectName("PassageMetaLabel")
        ph_layout.addWidget(self.lbl_passage_title)
        ph_layout.addWidget(self.lbl_passage_meta)
        left_layout.addWidget(self.passage_header_frame)

        # Rich Scripture Text Browser
        self.browser_scripture = QTextBrowser()
        self.browser_scripture.setOpenExternalLinks(False)
        self.browser_scripture.setFont(QFont("Liberation Serif", self.font_size))
        left_layout.addWidget(self.browser_scripture)

        splitter.addWidget(left_widget)

        # RIGHT PANEL: Studio Sidecar Tabs
        self.side_tabs = QTabWidget()

        # Tab 1: Search Results
        self.tab_search = QWidget()
        ts_layout = QVBoxLayout(self.tab_search)
        ts_layout.setContentsMargins(8, 8, 8, 8)
        self.lbl_search_summary = QLabel("Enter a search term above to search all 39,482 verses across 94 books.")
        self.lbl_search_summary.setStyleSheet("color: #C8A951; font-weight: bold;")
        ts_layout.addWidget(self.lbl_search_summary)

        self.list_search_results = QListWidget()
        self.list_search_results.itemDoubleClicked.connect(self._on_search_item_clicked)
        ts_layout.addWidget(self.list_search_results)
        self.side_tabs.addTab(self.tab_search, "🔎 Search Results (0)")

        # Tab 2: 94-Book Sacred Library
        self.tab_library = QWidget()
        tl_layout = QVBoxLayout(self.tab_library)
        tl_layout.setContentsMargins(8, 8, 8, 8)
        lbl_lib_info = QLabel("Double-click any of the 94 books below to read chapter 1 immediately:")
        lbl_lib_info.setStyleSheet("color: #E5C158; font-size: 11px;")
        tl_layout.addWidget(lbl_lib_info)

        self.table_books = QTableWidget()
        self.table_books.setColumnCount(5)
        self.table_books.setHorizontalHeaderLabels(["#", "Book Name", "Testament", "Category", "Chaps"])
        self.table_books.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.table_books.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        self.table_books.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        self.table_books.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        self.table_books.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
        self.table_books.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.table_books.cellDoubleClicked.connect(self._on_book_table_double_click)
        tl_layout.addWidget(self.table_books)
        self.side_tabs.addTab(self.tab_library, "📚 94-Book Library")

        # Tab 3: Hebrew / Greek Roots & Gematria
        self.tab_concordance = QWidget()
        tc_layout = QVBoxLayout(self.tab_concordance)
        tc_layout.setContentsMargins(8, 8, 8, 8)
        tc_layout.setSpacing(8)

        lbl_conc_title = QLabel("HEBREW / GREEK ROOTS & NUMERICAL GEMATRIA")
        lbl_conc_title.setStyleSheet("color: #FFD700; font-weight: bold; font-size: 12px;")
        tc_layout.addWidget(lbl_conc_title)

        self.browser_concordance = QTextBrowser()
        self.browser_concordance.setFont(QFont("Liberation Serif", 13))
        tc_layout.addWidget(self.browser_concordance)

        # AI Theological Philology Button
        btn_ai_study = QPushButton("✨ Deep Philology & Root Analysis (Ollama AI)")
        btn_ai_study.setObjectName("GoldBtn")
        btn_ai_study.clicked.connect(self.run_ai_philology)
        tc_layout.addWidget(btn_ai_study)

        self.side_tabs.addTab(self.tab_concordance, "🧬 Roots && Gematria")

        # Tab 4: Perez Lineage & Covenant Heritage
        self.tab_perez = QWidget()
        tp_layout = QVBoxLayout(self.tab_perez)
        tp_layout.setContentsMargins(8, 8, 8, 8)
        browser_perez = QTextBrowser()
        browser_perez.setFont(QFont("Liberation Serif", 13))
        browser_perez.setHtml(self._get_perez_heritage_html())
        tp_layout.addWidget(browser_perez)
        self.side_tabs.addTab(self.tab_perez, "👑 Perez Covenant")

        splitter.addWidget(self.side_tabs)
        splitter.setStretchFactor(0, 3) # Left takes 60%
        splitter.setStretchFactor(1, 2) # Right takes 40%

        root.addWidget(splitter, 1)

        # ----------------------------------------------------
        # BOTTOM STATUS BAR
        # ----------------------------------------------------
        status_bar = QHBoxLayout()
        status_bar.setContentsMargins(4, 2, 4, 2)
        self.lbl_status = QLabel(f"Ready • {EDITION_TITLE} • 94 Books • 39,482 Verses Indexed.")
        self.lbl_status.setStyleSheet("color: #A89872; font-size: 11px;")
        status_bar.addWidget(self.lbl_status)
        status_bar.addStretch()

        self.progress_bar = QProgressBar()
        self.progress_bar.setFixedWidth(160)
        self.progress_bar.setVisible(False)
        status_bar.addWidget(self.progress_bar)

        root.addLayout(status_bar)

        # Populate Book combo and Book Library table
        self._populate_books_filter("ALL")
        self._populate_library_table()

    def _populate_library_table(self):
        """Fill Tab 2 with all 94 books."""
        self.table_books.setRowCount(len(self.books))
        for row, b in enumerate(self.books):
            it_num = QTableWidgetItem(f"{b['num']:02d}")
            it_num.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            it_name = QTableWidgetItem(b["name"])
            it_test = QTableWidgetItem(b["testament"])
            it_test.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            it_cat = QTableWidgetItem(b["category"].capitalize())
            it_ch = QTableWidgetItem(str(b["chapters"]))
            it_ch.setTextAlignment(Qt.AlignmentFlag.AlignCenter)

            # Golden tint for Enochian / Apocrypha
            if b["testament"] == "EN":
                for it in (it_num, it_name, it_test, it_cat, it_ch):
                    it.setForeground(QColor("#FFD700"))
            elif b["testament"] == "AP":
                for it in (it_num, it_name, it_test, it_cat, it_ch):
                    it.setForeground(QColor("#E2CCA0"))

            self.table_books.setItem(row, 0, it_num)
            self.table_books.setItem(row, 1, it_name)
            self.table_books.setItem(row, 2, it_test)
            self.table_books.setItem(row, 3, it_cat)
            self.table_books.setItem(row, 4, it_ch)

    def _on_book_table_double_click(self, row, col):
        b = self.books[row]
        self.select_book_and_chapter(b["name"], 1)

    def _populate_books_filter(self, testament_code: str):
        """Populate the book dropdown filtered by testament."""
        self.combo_book.blockSignals(True)
        self.combo_book.clear()

        filtered = [b for b in self.books if testament_code == "ALL" or b["testament"] == testament_code]
        for b in filtered:
            display = f"{b['num']:02d}. {b['name']} ({b['abbr']})"
            self.combo_book.addItem(display, b["name"])

        self.combo_book.blockSignals(False)

    def _on_testament_changed(self, index):
        code = self.combo_testament.currentData()
        self._populate_books_filter(code)
        if self.combo_book.count() > 0:
            first_book_name = self.combo_book.itemData(0)
            self.select_book_and_chapter(first_book_name, 1)

    def _on_book_changed(self, index):
        book_name = self.combo_book.currentData()
        if not book_name:
            return
        self._populate_chapters(book_name)
        # Select first chapter
        first_chap = self.combo_chapter.itemData(0) or 1
        self.load_chapter_text(book_name, first_chap)

    def _populate_chapters(self, book_name: str):
        self.combo_chapter.blockSignals(True)
        self.combo_chapter.clear()

        chaps = sorted(self.bible_data.get(book_name, {}).keys())
        if not chaps:
            # Fallback to book metadata chapter count
            meta = self.books_by_name.get(book_name, {})
            chaps = list(range(1, meta.get("chapters", 1) + 1))

        for c in chaps:
            self.combo_chapter.addItem(f"Chapter {c}", c)

        self.combo_chapter.blockSignals(False)

    def _on_verse_changed(self, index):
        v = self.combo_verse.currentData()
        if v and v != "ALL":
            self.browser_scripture.scrollToAnchor(f"v{v}")

    def _populate_verses(self, sorted_verses, target_verse=None):
        self.combo_verse.blockSignals(True)
        self.combo_verse.clear()
        self.combo_verse.addItem("All Verses", "ALL")
        target_idx = 0
        for idx, v in enumerate(sorted_verses, start=1):
            self.combo_verse.addItem(f"Verse {v}", v)
            if target_verse is not None and v == target_verse:
                target_idx = idx
        self.combo_verse.setCurrentIndex(target_idx)
        self.combo_verse.blockSignals(False)

    def _on_chapter_changed(self, index):
        book_name = self.combo_book.currentData()
        chap = self.combo_chapter.currentData()
        if book_name and chap is not None:
            self.load_chapter_text(book_name, chap)

    def prev_chapter(self):
        curr_idx = self.combo_chapter.currentIndex()
        if curr_idx > 0:
            self.combo_chapter.setCurrentIndex(curr_idx - 1)
        else:
            # Go to previous book if available
            b_idx = self.combo_book.currentIndex()
            if b_idx > 0:
                self.combo_book.setCurrentIndex(b_idx - 1)
                last_ch_idx = self.combo_chapter.count() - 1
                if last_ch_idx >= 0:
                    self.combo_chapter.setCurrentIndex(last_ch_idx)

    def next_chapter(self):
        curr_idx = self.combo_chapter.currentIndex()
        if curr_idx < self.combo_chapter.count() - 1:
            self.combo_chapter.setCurrentIndex(curr_idx + 1)
        else:
            # Go to next book
            b_idx = self.combo_book.currentIndex()
            if b_idx < self.combo_book.count() - 1:
                self.combo_book.setCurrentIndex(b_idx + 1)

    def _on_flagship_selected(self, index):
        if index == 0:
            return
        data = self.combo_flagship.currentData()
        if data:
            b_name, ch = data
            self.select_book_and_chapter(b_name, ch)

    def select_book_and_chapter(self, book_name: str, chapter: int):
        """Navigate cleanly to any book and chapter across all 94 books."""
        meta = self.books_by_name.get(book_name)
        if not meta:
            return

        # Ensure testament filter includes this book
        curr_test = self.combo_testament.currentData()
        if curr_test != "ALL" and curr_test != meta["testament"]:
            self.combo_testament.blockSignals(True)
            self.combo_testament.setCurrentIndex(0) # All 94 Books
            self.combo_testament.blockSignals(False)
            self._populate_books_filter("ALL")

        # Set Book combo
        self.combo_book.blockSignals(True)
        for i in range(self.combo_book.count()):
            if self.combo_book.itemData(i) == book_name:
                self.combo_book.setCurrentIndex(i)
                break
        self.combo_book.blockSignals(False)

        # Repopulate chapters
        self._populate_chapters(book_name)

        # Set Chapter combo
        self.combo_chapter.blockSignals(True)
        for i in range(self.combo_chapter.count()):
            if self.combo_chapter.itemData(i) == chapter:
                self.combo_chapter.setCurrentIndex(i)
                break
        self.combo_chapter.blockSignals(False)

        # Load text
        self.load_chapter_text(book_name, chapter)

    def load_chapter_text(self, book_name: str, chapter: int):
        """Render the complete chapter in rich sovereign HTML with verse numbers and covenant highlights."""
        self.current_book = book_name
        self.current_chapter = chapter

        meta = self.books_by_name.get(book_name, {})
        num = meta.get("num", 0)
        abbr = meta.get("abbr", "")
        testament = meta.get("testament", "")
        cat = meta.get("category", "").upper()
        canon = meta.get("canon", "")
        perez_notes = meta.get("perez", "")

        testament_full = TESTAMENT_LABELS.get(testament, testament)

        # Update Header Frame
        self.lbl_passage_title.setText(f"{book_name.upper()} — CHAPTER {chapter}")
        meta_str = f"BOOK #{num:02d} • {testament_full.upper()} • {cat} • {canon.upper()}"
        if perez_notes and perez_notes != "NULL":
            meta_str += f" • 👑 {perez_notes}"
        self.lbl_passage_meta.setText(meta_str)

        # Retrieve verses
        verses = self.bible_data.get(book_name, {}).get(chapter, {})
        self.current_verses = verses

        if not verses:
            html = f"""
            <div style="padding: 30px; text-align: center; color: #D4AF37;">
                <h2>No Verses Found</h2>
                <p>Could not locate verses for {book_name} Chapter {chapter} in {BIBLE_TSV}.</p>
            </div>
            """
            self.browser_scripture.setHtml(html)
            self.lbl_status.setText(f"⚠️ No verses found for {book_name} {chapter}.")
            return

        # Build Rich HTML
        sorted_verses = sorted(verses.keys())
        self._populate_verses(sorted_verses)
        html_parts = []
        html_parts.append(f"""
        <html>
        <head>
            <style>
                body {{
                    background-color: #0B0C10;
                    color: #F7EFE1;
                    font-family: 'Liberation Serif', 'Georgia', serif;
                    font-size: {self.font_size}px;
                    line-height: 1.65;
                    margin: 10px;
                }}
                .header-card {{
                    background-color: #141724;
                    border-bottom: 2px solid #D4AF37;
                    padding: 10px 14px;
                    margin-bottom: 18px;
                    border-radius: 6px;
                }}
                .verse {{
                    margin-bottom: 12px;
                    padding: 2px 4px;
                }}
                .verse-num {{
                    color: #FFD700;
                    font-weight: bold;
                    font-size: 0.85em;
                    margin-right: 6px;
                    display: inline-block;
                }}
                .highlight-divine {{
                    color: #FFE599;
                    font-weight: bold;
                }}
                .highlight-perez {{
                    color: #FFD700;
                    background-color: #382D0F;
                    padding: 1px 4px;
                    border-radius: 3px;
                    font-weight: bold;
                }}
            </style>
        </head>
        <body>
        """)

        # Perez Covenant banner inside chapter if applicable
        if perez_notes and perez_notes != "NULL":
            html_parts.append(f"""
            <div class="header-card">
                <span style="color: #FFD700; font-weight: bold;">👑 PEREZ COVENANT REFERENCE:</span>
                <span style="color: #F4ECD8;"> {perez_notes}</span>
            </div>
            """)

        full_chapter_plain = []
        for v_num in sorted_verses:
            v_text = verses[v_num]
            full_chapter_plain.append(f"{chapter}:{v_num} {v_text}")

            # Highlight divine titles and Perez
            display_text = v_text
            display_text = re.sub(r'\b(Perez|Pharez|Phares|PERES)\b', r'<span class="highlight-perez">\1</span>', display_text, flags=re.IGNORECASE)
            display_text = re.sub(r'\b(LORD|GOD|JESUS|CHRIST|SAVIOUR|HOLY GHOST)\b', r'<span class="highlight-divine">\1</span>', display_text)

            html_parts.append(f"""
            <a name="v{v_num}"></a>
            <div class="verse" id="v{v_num}">
                <span class="verse-num">[{v_num}]</span>
                <span class="verse-text">{display_text}</span>
            </div>
            """)

        html_parts.append("</body></html>")
        self.browser_scripture.setHtml("".join(html_parts))

        # Update Status
        self.lbl_status.setText(f"📖 Loaded {book_name} {chapter} ({len(sorted_verses)} verses) • {EDITION_TITLE}")

        # Update Concordance Panel for this chapter
        self._update_concordance_panel(book_name, chapter, "\n".join(full_chapter_plain))

    def _update_concordance_panel(self, book_name: str, chapter: int, chapter_text: str):
        """Render immediate offline Root Concordance, Gematria & Cross-References for current chapter."""
        meta = self.books_by_name.get(book_name, {})
        g = compute_gematria(chapter_text)

        testament = meta.get("testament", "")
        orig_lang = "Ancient Hebrew & Aramaic" if testament in ("OT", "EN") else ("Koine Greek" if testament == "NT" else "Greek & Semitic Deuterocanon")

        html = f"""
        <html>
        <body style="color: #F4ECD8; font-family: 'Liberation Serif', serif; font-size: 13px; line-height: 1.5;">
            <div style="background-color: #151822; padding: 10px; border-radius: 6px; border: 1px solid #D4AF37; margin-bottom: 12px;">
                <b style="color: #FFD700; font-size: 14px;">{book_name.upper()} {chapter} — ROOT CONCORDANCE</b><br/>
                <span style="color: #C8A951; font-size: 11px;">Original Philological Tongue: <b>{orig_lang}</b></span>
            </div>

            <table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;">
                <tr style="background-color: #1A1E2B;">
                    <th style="color: #FFD700; padding: 5px; text-align: left; border: 1px solid #332B1A;">Metric</th>
                    <th style="color: #FFD700; padding: 5px; text-align: left; border: 1px solid #332B1A;">Value</th>
                </tr>
                <tr>
                    <td style="padding: 5px; border: 1px solid #332B1A;">Total Verses</td>
                    <td style="padding: 5px; border: 1px solid #332B1A; color: #FFD700; font-weight: bold;">{len(self.current_verses)}</td>
                </tr>
                <tr>
                    <td style="padding: 5px; border: 1px solid #332B1A;">Word Count</td>
                    <td style="padding: 5px; border: 1px solid #332B1A;">{g['word_count']} words</td>
                </tr>
                <tr>
                    <td style="padding: 5px; border: 1px solid #332B1A;">English Ordinal Gematria</td>
                    <td style="padding: 5px; border: 1px solid #332B1A; color: #FFE082; font-weight: bold;">{g['ordinal']:,}</td>
                </tr>
                <tr>
                    <td style="padding: 5px; border: 1px solid #332B1A;">Sumerian Gematria (Base 6)</td>
                    <td style="padding: 5px; border: 1px solid #332B1A; color: #FFE082; font-weight: bold;">{g['sumerian']:,}</td>
                </tr>
                <tr>
                    <td style="padding: 5px; border: 1px solid #332B1A;">Canon Classification</td>
                    <td style="padding: 5px; border: 1px solid #332B1A;">{meta.get('canon', 'Sacred Scripture')}</td>
                </tr>
            </table>

            <div style="background-color: #11131A; padding: 10px; border-radius: 6px; border: 1px solid #2B2315; margin-bottom: 12px;">
                <b style="color: #FFD700;">KEY THEOLOGICAL ROOTS & CONCORDANCE:</b><br/>
                <ul style="margin-top: 6px; padding-left: 18px;">
                    <li><b>PEREZ (×¤Ö¶Ö¼×¨Ö¶×¥):</b> <i>Perets</i> (Strong's H6557) — "A breach, breaking forth, breakthrough, division." The unbroken royal seed leading directly from Judah & Tamar to David and King Jesus.</li>
                    <li><b>LOGOS (Î›ÏŒÎ³Î¿Ï‚):</b> (Strong's G3056) — "The Divine Word, Reason, Creative Decree of God." (John 1:1, 1 Enoch 14).</li>
                    <li><b>YESHUA / JESUS (×™Öµ×©××•Ö¼×¢Ö·):</b> <i>Y'hoshua</i> (Strong's H3091 / G2424) — "Yahweh is Salvation, The Deliverer, The Sovereign King."</li>
                    <li><b>ELOHIM (×Ö±×œÖ¹×”Ö´×™×):</b> (Strong's H430) — "The Supreme Mighty God, Creator of Heaven and Earth."</li>
                    <li><b>RUACH HAKODESH (×¨×•Ö¼×—Ö· ×”Ö·×§Ö¹Ö¼×“Ö¶×©×):</b> "The Holy Spirit, The Breath of Life." (Genesis 1:2, Psalm 51:11).</li>
                </ul>
            </div>

            <div style="color: #A09882; font-size: 11px;">
                <i>Click "Deep Philology & Root Analysis (Ollama AI)" below to run advanced linguistic analysis using local neural models.</i>
            </div>
        </body>
        </html>
        """
        self.browser_concordance.setHtml(html)

    def _get_perez_heritage_html(self) -> str:
        """HTML summary of the Perez Lineage and Covenant foundations."""
        return f"""
        <html>
        <body style="color: #F4ECD8; font-family: 'Liberation Serif', serif; font-size: 13.5px; line-height: 1.6;">
            <div style="background-color: #141724; padding: 12px; border-radius: 6px; border: 1px solid #D4AF37; margin-bottom: 14px;">
                <h3 style="color: #FFD700; margin: 0 0 6px 0;">👑 THE ROYAL LINEAGE & BLESSING OF PEREZ</h3>
                <span style="color: #C8A951;">The Covenant Foundation of the Authorized King Jesus Version (Perez Edition)</span>
            </div>

            <p>The name <b>PEREZ</b> (Hebrew: <b>×¤Ö¶Ö¼×¨Ö¶×¥</b>, <i>Perets</i>, meaning <i>"The Breakthrough"</i> or <i>"Breach"</i>) is one of the most profound covenantal keystones in all of Sacred Scripture. It represents the miraculous breakthrough of God's sovereign decree over human limitation.</p>

            <h4 style="color: #FFD700; border-bottom: 1px solid #332B1A; padding-bottom: 4px;">1. The Birth of the Breakthrough (Genesis 38:29)</h4>
            <p><i>"And it came to pass, as he drew back his hand, that, behold, his brother came out: and she said, How hast thou broken forth? this breach be upon thee: therefore his name was called <b>Perez</b>."</i></p>

            <h4 style="color: #FFD700; border-bottom: 1px solid #332B1A; padding-bottom: 4px;">2. The Blessing of the Elders of Bethlehem (Ruth 4:12, 18-22)</h4>
            <p><i>"And let thy house be like the house of <b>Perez</b>, whom Tamar bare unto Judah, of the seed which the LORD shall give thee of this young woman... Now these are the generations of <b>Perez</b>: Perez begat Hezron, and Hezron begat Ram, and Ram begat Amminadab... and Jesse begat <b>David</b>."</i></p>

            <h4 style="color: #FFD700; border-bottom: 1px solid #332B1A; padding-bottom: 4px;">3. The Sovereign Genealogy of King Jesus (Matthew 1:3 & Luke 3:33)</h4>
            <p><i>"And Judas begat <b>Perez</b> and Zarah of Thamar; and Perez begat Esrom... and David the king begat Solomon... and Jacob begat Joseph the husband of Mary, of whom was born <b>Jesus, who is called Christ</b>."</i></p>

            <h4 style="color: #FFD700; border-bottom: 1px solid #332B1A; padding-bottom: 4px;">4. The Divine Verdict: PERES (Daniel 5:28)</h4>
            <p><i>"<b>PERES</b>; Thy kingdom is divided, and given to the Medes and Persians."</i> The supernatural hand of God writes the root PERES upon the wall, executing righteous divine judgment and transferring dominion.</p>

            <h4 style="color: #FFD700; border-bottom: 1px solid #332B1A; padding-bottom: 4px;">5. The 94-Book Scope of the Sacred Canon</h4>
            <p>The <b>Authorized King Jesus Version (Perez Edition)</b> maintains all 94 Books of Sacred Scripture, reuniting:</p>
            <ul>
                <li><b>The 39 Books of the Old Testament</b> (Genesis to Malachi)</li>
                <li><b>The 27 Books of the New Testament</b> (Matthew to Revelation)</li>
                <li><b>The 14 Books of the 1611 Apocrypha</b> (1 & 2 Esdras, Tobit, Judith, Wisdom, Sirach, Baruch, Maccabees)</li>
                <li><b>The 14 Books of the Enochian & Patriarchal Canon</b> (1, 2 & 3 Enoch, Jubilees, Testaments of the Patriarchs, Ascension of Isaiah, Apocalypse of Abraham, Giants, Life of Adam & Eve, Testament of Moses, 2 Baruch, Apocalypse of Peter, Epistle of Barnabas, and Shepherd of Hermas).</li>
            </ul>
        </body>
        </html>
        """

    def perform_search(self):
        """Instant search across all 39,482 verses in 94 books."""
        raw_query = self.input_search.text().strip()
        if not raw_query:
            return

        # Check if reference like "John 3:16" or "Genesis 1" or "1 Enoch 1:9"
        ref_match = re.match(r'^([\d\s\w]+?)\s+(\d+)(?::(\d+))?$', raw_query)
        if ref_match:
            b_cand, ch_cand, v_cand = ref_match.groups()
            b_cand_clean = b_cand.strip().lower()
            ch_num = int(ch_cand)

            matched_book = None
            for b in self.books:
                if b["name"].lower() == b_cand_clean or b["abbr"].lower() == b_cand_clean:
                    matched_book = b["name"]
                    break

            if matched_book:
                self.select_book_and_chapter(matched_book, ch_num)
                self.lbl_status.setText(f"🔎 Jumped to reference: {matched_book} {ch_num}")
                return

        # Keyword search across all verses
        q = raw_query.lower()
        results = []
        for b in self.books:
            b_name = b["name"]
            testament = b["testament"]
            if b_name not in self.bible_data:
                continue
            for ch, v_dict in self.bible_data[b_name].items():
                for v_num, v_text in v_dict.items():
                    if q in v_text.lower():
                        results.append((b_name, ch, v_num, testament, v_text))
                        if len(results) >= 500: # safety cap
                            break
                if len(results) >= 500:
                    break
            if len(results) >= 500:
                break

        # Populate Search Results List
        self.list_search_results.clear()
        self.side_tabs.setTabText(0, f"🔎 Search Results ({len(results)})")
        self.side_tabs.setCurrentIndex(0) # switch to search tab

        if not results:
            self.lbl_search_summary.setText(f"No verses found matching '{raw_query}'.")
            self.lbl_status.setText(f"No results for '{raw_query}'.")
            return

        self.lbl_search_summary.setText(f"Found {len(results)} verse{'s' if len(results) > 1 else ''} matching '{raw_query}':")
        for b_name, ch, v_num, test, v_text in results:
            snippet = v_text[:110] + ("..." if len(v_text) > 110 else "")
            item_text = f"[{test}] {b_name} {ch}:{v_num} — {snippet}"
            item = QListWidgetItem(item_text)
            item.setData(Qt.ItemDataRole.UserRole, (b_name, ch, v_num))
            if test == "EN":
                item.setForeground(QColor("#FFD700"))
            elif test == "AP":
                item.setForeground(QColor("#E2CCA0"))
            self.list_search_results.addItem(item)

        self.lbl_status.setText(f"✅ Found {len(results)} matches for '{raw_query}' in {EDITION_TITLE}.")

    def _on_search_item_clicked(self, item: QListWidgetItem):
        data = item.data(Qt.ItemDataRole.UserRole)
        if data:
            b_name, ch, v_num = data
            self.select_book_and_chapter(b_name, ch)

    def clear_search(self):
        self.input_search.clear()
        self.list_search_results.clear()
        self.side_tabs.setTabText(0, "🔎 Search Results (0)")
        self.lbl_search_summary.setText("Enter a search term above to search all 39,482 verses across 94 books.")

    def adjust_font(self, delta: int):
        self.font_size = max(11, min(32, self.font_size + delta))
        if self.current_book and self.current_chapter:
            self.load_chapter_text(self.current_book, self.current_chapter)

    def copy_current_chapter(self):
        cb = QApplication.clipboard()
        if cb and self.current_book and self.current_verses:
            lines = [f"=== {EDITION_TITLE.upper()} — {self.current_book.upper()} {self.current_chapter} ===\n"]
            for v_num in sorted(self.current_verses.keys()):
                lines.append(f"{self.current_chapter}:{v_num} {self.current_verses[v_num]}")
            full_text = "\n".join(lines)
            cb.setText(full_text)
            self.lbl_status.setText(f"📋 Copied {self.current_book} {self.current_chapter} to clipboard.")

    def open_pdf(self):
        pdf_file = PDF_PATH if os.path.exists(PDF_PATH) else os.path.join(FALLBACK_DATA_DIR, "akjv-perez-edition.pdf")
        if not os.path.exists(pdf_file):
            QMessageBox.warning(self, "PDF Not Found", f"Could not find PDF at {pdf_file}")
            return
        try:
            if shutil.which("okular"):
                subprocess.Popen(["okular", pdf_file])
            elif shutil.which("xdg-open"):
                subprocess.Popen(["xdg-open", pdf_file])
            self.lbl_status.setText(f"📖 Opened {pdf_file} in PDF viewer.")
        except Exception as e:
            QMessageBox.warning(self, "Error Opening PDF", str(e))

    def start_reading_aloud(self):
        if not self.current_verses:
            return
        self.stop_reading_aloud()

        lines = []
        for v in sorted(self.current_verses.keys()):
            lines.append(self.current_verses[v])
        full_text = f"{self.current_book} chapter {self.current_chapter}. " + " ".join(lines)

        self.btn_audio.setEnabled(False)
        self.btn_stop_audio.setEnabled(True)
        self.lbl_status.setText(f"🔊 Reading {self.current_book} {self.current_chapter} aloud...")

        self.audio_worker = AudioNarrationWorker(full_text)
        self.audio_worker.finished_signal.connect(self._on_audio_finished)
        self.audio_worker.status_signal.connect(lambda s: self.lbl_status.setText(s))
        self.audio_worker.start()

    def stop_reading_aloud(self):
        if self.audio_worker and self.audio_worker.isRunning():
            self.audio_worker.stop()
        self.btn_audio.setEnabled(True)
        self.btn_stop_audio.setEnabled(False)
        self.lbl_status.setText("⏹ Audio reading stopped.")

    def _on_audio_finished(self):
        self.btn_audio.setEnabled(True)
        self.btn_stop_audio.setEnabled(False)
        self.lbl_status.setText(f"✅ Finished reading {self.current_book} {self.current_chapter}.")

    def run_ai_philology(self):
        """Query Alfred Sovereign AI Mesh (local or Gigabyte Workstation) for deep root philology."""
        self.lbl_status.setText("✨ Scanning Alfred Sovereign AI Neural Mesh for theological philology...")

        mesh_endpoints = [
            "http://127.0.0.1:11434",
            "http://192.168.1.126:11434",
            "http://alfred-g5kf5:11434"
        ]

        active_endpoint = None
        models = []
        for ep in mesh_endpoints:
            try:
                req = urllib.request.Request(f"{ep}/api/tags", method="GET")
                with urllib.request.urlopen(req, timeout=2) as resp:
                    data = json.loads(resp.read().decode("utf-8", errors="replace"))
                    models = [m.get("name", "") for m in data.get("models", [])]
                    active_endpoint = ep
                    break
            except Exception:
                continue

        if not active_endpoint:
            self.lbl_status.setText("ℹ️  Neural Mesh offline. Rich built-in Concordance & Gematria is already displayed above.")
            QMessageBox.information(
                self,
                "Alfred Neural Mesh Offline",
                "Ollama is not currently reachable on 127.0.0.1 or 192.168.1.126.\n\n"
                "The built-in Strong's Concordance, Numerical Gematria, and Root Word analysis displayed in the panel is 100% operational offline!"
            )
            return

        # Prefer alfred-haiku or alfred-coder, else first available
        model = "alfred-haiku:latest" if "alfred-haiku:latest" in models else (models[0] if models else "alfred-haiku:latest")
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)
        self.lbl_status.setText(f"✨ Running deep neural root analysis via {model} on {active_endpoint}...")

        # Run in background worker
        text_sample = " ".join([f"{v}: {self.current_verses[v]}" for v in sorted(self.current_verses.keys())[:8]])
        prompt = (
            f"You are the Sovereign Biblical Philologist for {EDITION_TITLE}.\n"
            f"Provide an academic root word study for {self.current_book} chapter {self.current_chapter}.\n"
            f"Include:\n1. Hebrew/Aramaic/Greek root vocabulary with Strong's references.\n"
            f"2. Gematria covenant symbolism.\n3. Perez covenant parallels.\n\n"
            f"Text:\n{text_sample[:1500]}"
        )

        def worker():
            try:
                payload = json.dumps({"model": model, "prompt": prompt, "stream": False}).encode("utf-8")
                req = urllib.request.Request(f"{active_endpoint}/api/generate", data=payload, headers={"Content-Type": "application/json"}, method="POST")
                with urllib.request.urlopen(req, timeout=60) as resp:
                    res_data = json.loads(resp.read().decode("utf-8", errors="replace"))
                    analysis = clean_branding(res_data.get("response", ""))
                    QTimer.singleShot(0, lambda: self._on_ai_philology_done(analysis))
            except Exception as e:
                QTimer.singleShot(0, lambda: self._on_ai_philology_error(str(e)))

        import threading
        t = threading.Thread(target=worker, daemon=True)
        t.start()
    def _on_ai_philology_done(self, analysis: str):
        self.progress_bar.setVisible(False)
        self.lbl_status.setText(f"✅ AI Root Philology complete for {self.current_book} {self.current_chapter}.")
        existing = self.browser_concordance.toHtml()
        ai_block = f"""
        <div style="margin-top: 15px; padding: 12px; background-color: #161A26; border: 1px solid #FFD700; border-radius: 6px;">
            <b style="color: #FFD700;">✨ NEURAL ROOT PHILOLOGY & COVENANT INSIGHTS:</b>
            <pre style="white-space: pre-wrap; font-family: 'Liberation Serif', serif; color: #F7EFE1; font-size: 13px; line-height: 1.5;">{analysis}</pre>
        </div>
        """
        self.browser_concordance.setHtml(existing + ai_block)

    def _on_ai_philology_error(self, err: str):
        self.progress_bar.setVisible(False)
        self.lbl_status.setText(f"⚠️ AI Philology query error: {err}")


def main():
    app = QApplication(sys.argv)
    app.setApplicationName(f"Alfred Scripture Studio — {EDITION_TITLE}")
    win = BibleStudioWindow()
    win.showMaximized()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
