"""
SWORD module reader — provides access to 250+ free Bible modules.

Uses pysword (MIT) to read CrossWire/SWORD Bible texts directly.
Prioritizes rare-language modules unavailable in Accordance format.

Module-level imports are safe without pysword installed.
SwordImporter.__init__ raises a clear error if pysword is missing.
"""

from __future__ import annotations

from typing import Dict, Optional


# ---------------------------------------------------------------------------
# Deferred pysword import — module remains importable without pysword
# ---------------------------------------------------------------------------

_pysword = None
_pysword_error: Optional[ImportError] = None

try:
    import pysword  # type: ignore[import-untyped]

    _pysword = pysword
except ImportError as exc:
    _pysword_error = exc


_PYSWORD_INSTALL_MSG = (
    "pysword is not installed. Install it with:\n"
    "    pip install pysword\n\n"
    "You also need SWORD modules installed locally. On macOS:\n"
    "    brew install sword && installmgr -init && installmgr -r CrossWire\n"
    "    installmgr -ri CrossWire KJV CopNT Geez\n"
    "On Linux:\n"
    "    sudo apt install sword-comm-mhcc libsword-utils\n"
    "Or use Xiphos / BPBible (cross-platform GUI) for module management."
)


# ---------------------------------------------------------------------------
# Priority module list — rare-language modules
# ---------------------------------------------------------------------------

PRIORITY_MODULES: Dict[str, str] = {
    # 🔴 Unique languages — no Accordance equivalent
    "CopNT": "Coptic (New Testament — Sahidic)",
    "CopSahHorner": "Coptic (Sahidic, Horner edition)",
    "CopSahidicMSS": "Coptic (Sahidic manuscripts)",
    "CopBo": "Coptic (Bohairic)",
    "Geez": "Ge'ez / Ethiopic",
    "ArmEastern": "Armenian (Eastern)",
    "ArmWestern": "Armenian (Western)",
    # 🟠 Unique historical texts
    "Wulfila": "Gothic Bible (4th century, Wulfila)",
    "Etheridge": "English translation of Syriac Peshitta (Etheridge)",
    "Murdock": "English translation of Syriac Peshitta (Murdock)",
    # 🟡 Morphological / supplemental
    "MorphGNT": "Greek NT with morphology (SBLGNT-based)",
    "LXX": "Septuagint (Greek OT)",
    "LXXM": "Septuagint with morphology",
    # 🟢 Niche liturgical
    "CSlElizabeth": "Church Slavonic (Elizabeth Bible)",
    "Vulgate": "Latin Vulgate",
    "VulgClementine": "Latin Vulgate (Clementine)",
    "Tischendorf": "Greek NT (Tischendorf 8th ed.)",
    "WestcottHort": "Greek NT (Westcott-Hort)",
    "Byz": "Greek NT (Byzantine Majority)",
}


# ---------------------------------------------------------------------------
# SwordImporter
# ---------------------------------------------------------------------------


class SwordImporter:
    """Imports SWORD Bible modules into Accordance Port.

    Reads CrossWire/SWORD Bible modules directly via pysword (MIT, pure Python).
    Provides access to 250+ Bible translations including rare-language texts
    with no Accordance equivalent (Coptic, Ge'ez, Armenian, Gothic, Syriac).

    Usage:
        >>> importer = SwordImporter()          # default SWORD path
        >>> importer = SwordImporter("~/.sword")  # explicit path
        >>> modules = importer.list_modules()
        >>> text = importer.get_verse("CopNT", "John", 1, 1)
    """

    # Priority modules: rare-language texts unavailable in Accordance format.
    # Coptic, Ge'ez, Armenian, Gothic, Syriac, Church Slavonic, plus
    # morphological and critical Greek editions.
    PRIORITY = PRIORITY_MODULES

    def __init__(self, modules_path: Optional[str] = None) -> None:
        """Initialize SWORD module reader.

        Args:
            modules_path: Path to SWORD modules directory.
                          Defaults to None (pysword auto-discovers ~/.sword
                          and other standard SWORD paths).

        Raises:
            ImportError: If pysword is not installed, with installation
                         instructions.
        """
        if _pysword is None:
            raise ImportError(_PYSWORD_INSTALL_MSG) from _pysword_error

        self._pysword = _pysword
        self._modules_path = modules_path

    def list_modules(self) -> dict:
        """List all available SWORD modules with metadata.

        Returns:
            dict[str, dict]: Module name → metadata dict with keys like
            'description', 'language', 'category', 'version'.

        Raises:
            RuntimeError: If no SWORD modules are found at the configured path.
        """
        manager = self._pysword.SwordModules(self._modules_path)
        try:
            return manager.parse_modules()
        except Exception:
            return {}

    def get_verse(self, module: str, book: str, chapter: int, verse: int) -> str:
        """Get a single verse from a SWORD module.

        Args:
            module: SWORD module name (e.g., 'KJV', 'CopNT', 'MorphGNT').
            book: Book name in pysword-compatible form (e.g., 'Genesis', 'John').
                  OSIS-style abbreviations (e.g., 'Gen', 'Matt') also accepted.
            chapter: Chapter number (1-indexed).
            verse: Verse number (1-indexed).

        Returns:
            Verse text as a string, or empty string if not found.

        Examples:
            >>> importer = SwordImporter()
            >>> importer.get_verse("KJV", "Genesis", 1, 1)
            'In the beginning God created the heaven and the earth.'
            >>> importer.get_verse("CopNT", "John", 1, 1)  # Coptic
        """
        manager = self._pysword.SwordModules(self._modules_path)
        bible = manager.get_bible(module)
        if bible is None:
            return ""
        result = bible.get(books=[book], chapters=[chapter], verses=[verse])
        return result if result else ""

    def get_chapter(self, module: str, book: str, chapter: int) -> Dict[int, str]:
        """Get all verses in a chapter from a SWORD module.

        Args:
            module: SWORD module name.
            book: Book name.
            chapter: Chapter number (1-indexed).

        Returns:
            Dict of {verse_number: verse_text}.
        """
        manager = self._pysword.SwordModules(self._modules_path)
        bible = manager.get_bible(module)
        if bible is None:
            return {}
        # pysword returns a dict keyed by verse number for a chapter range
        result = bible.get(books=[book], chapters=[chapter])
        return result if isinstance(result, dict) else {}

    @property
    def modules_path(self) -> Optional[str]:
        """The configured SWORD modules directory, or None for auto-detect."""
        return self._modules_path

    def __repr__(self) -> str:
        path = self._modules_path or "auto"
        return f"SwordImporter(modules_path={path!r})"


# ---------------------------------------------------------------------------
# Module-level convenience: report pysword status on import
# ---------------------------------------------------------------------------

if _pysword is None:
    print(
        "accordance_parser.sword_importer: pysword not installed. "
        "SwordImporter will raise ImportError at init. "
        "Install with: pip install pysword"
    )
