from __future__ import annotations

import logging
import os

from mcp.server.fastmcp import FastMCP

logger = logging.getLogger(__name__)

mcp = FastMCP("Accordance Bible Library", json_response=True)

# ====================== INITIALIZE SERVICES ======================
from accordance_services.module_registry import init_modules  # noqa: E402

# Skip expensive module loading when ACCORDANCE_SKIP_MODULE_INIT is set
# (e.g. during test collection).  The module-level dicts are populated
# lazily on first access via text_modules() / lexicon_modules() / etc.
if not os.environ.get("ACCORDANCE_SKIP_MODULE_INIT"):
    init_modules()

# search_service auto-inits on import (starts background index build)
from accordance_services import search_service  # noqa: E402, F401

# ====================== REGISTER TOOL MODULES ======================
from accordance_services.tools import infra  # noqa: E402

infra.register(mcp)

from accordance_services.tools import text  # noqa: E402

text.register(mcp)

from accordance_services.tools import lexicon  # noqa: E402

lexicon.register(mcp)

from accordance_services.tools import commentary  # noqa: E402

commentary.register(mcp)

from accordance_services.tools import study  # noqa: E402

study.register(mcp)

from accordance_services.tools import strongs  # noqa: E402

strongs.register(mcp)

from accordance_services.tools import apparatus  # noqa: E402

apparatus.register(mcp)

from accordance_services.tools import catholic  # noqa: E402

catholic.register(mcp)

from accordance_services.tools import external  # noqa: E402

external.register(mcp)

from accordance_services.tools import acc2  # noqa: E402

acc2.register(mcp)

from accordance_services.tools import lookup_engine  # noqa: E402

lookup_engine.register(mcp)

from accordance_services.tools import cross_source  # noqa: E402

cross_source.register(mcp)

from accordance_services.tools import search  # noqa: E402

search.register(mcp)

from accordance_services.tools import openbible  # noqa: E402

openbible.register(mcp)

# ====================== LEGACY IMPORTS (backward-compat re-exports only) ======================
# These functions are already registered by services (text.py, commentary.py,
# strongs.py, search.py).  Imported here only so tests can do:
#   from accordance_mcp_server import get_book_list
from accordance_services.tools.text import (  # noqa: E402, F401
    get_book_list,
    get_chapter_list,
    get_verse_range,
)
from accordance_services.tools.commentary import compare_commentaries  # noqa: E402, F401
from accordance_services.tools.strongs import (  # noqa: E402, F401
    search_verses_by_strongs,
    strongs_frequency_list,
)
from accordance_services.tools.search import search_verses_by_term  # noqa: E402, F401


# ====================== BACKWARD-COMPAT RE-EXPORTS ======================
# Tests and scripts import these from accordance_mcp_server.
# They were moved to accordance_services/ during the Session 93 refactor.

from accordance_services.config import (  # noqa: E402, F401
    _BOOK_ID_TO_TESTAMENT,
    _COMMENTARY_TIERS,
    _get_tier_label,
    OT_KEYWORDS,
    is_ot,
    _CATHOLIC_SCHEDULE,
    _CANONICAL_SCHEDULE,
    _CHRONOLOGICAL_SCHEDULE,
    _NT_FIRST_SCHEDULE,
    _PSALMS_PROVERBS_SCHEDULE,
    get_reading_plan,
)
from accordance_services.helpers import (  # noqa: E402
    pair_strongs_with_text as _pair_strongs_with_text,  # noqa: F401 — backward compat
)
from accordance_services.search_service import get_search_index as _get_search_index  # noqa: E402, F401
from accordance_services.strongs_service import (  # noqa: E402, F401
    _ensure_strongs_index,
    get_strongs_index as _get_strongs_index,
    ref_to_str as _ref_to_str,
)

# Module dicts (populated by init_modules() above)
from accordance_services import module_registry as _mreg  # noqa: E402

_text_modules = _mreg._text_modules
_lexicon_modules = _mreg._lexicon_modules
_commentary_modules = _mreg._commentary_modules
_available_lexicons = _mreg._available_lexicons
_available_commentaries = _mreg._available_commentaries

# ---- Backward-compat: tool functions called as module-level attributes ----
# Tests call these directly on the module. After the Session 93 refactor,
# tools are registered on mcp via services. These wrappers call the
# underlying tool implementations directly for sync access.


def _list_tools_impl() -> str:
    from accordance_services.module_registry import commentary_modules

    com_mods = commentary_modules()
    out = "# Available Tool Modules\n\n"
    for abbr, cm in sorted(com_mods.items()):
        if getattr(cm, "format", None) == "generic":
            tier = _COMMENTARY_TIERS.get(abbr, 4)
            tier_str = _get_tier_label(tier)
            entries = len(cm._entries) if hasattr(cm, "_entries") else "?"
            out += f"- **{abbr}** ({tier_str}, {entries} sections)\n"
    return out


def _browse_tool_impl(module: str) -> str:
    from accordance_services.module_registry import commentary_modules

    com_mods = commentary_modules()
    if module not in com_mods:
        return f"[Tool '{module}' not found]"
    cm = com_mods[module]
    entries = getattr(cm, "_entries", [])
    out = f"# {module}\n\n"
    shown = 0
    for entry in entries:
        try:
            num = entry[0]
            text = cm._read_section(num)
            preview = text[:200].replace("\n", " ") if text else "(empty)"
            out += f"## {num}\n{preview}\n\n"
            shown += 1
            if shown >= 30:
                out += f"\n*(showing 30 of {len(entries)} sections)*\n"
                break
        except Exception:
            out += f"## {num}\n*(error reading)*\n\n"
            shown += 1
    return out


def _get_tool_section_impl(module: str, section: str) -> str:
    from accordance_services.module_registry import commentary_modules

    com_mods = commentary_modules()
    if module not in com_mods:
        return f"[Tool '{module}' not found]"
    cm = com_mods[module]
    try:
        return cm._read_section(section) or f"[Section {section} not found in {module}]"
    except Exception as e:
        return f"[Error reading section {section} in {module}: {e}]"


# Module-level backward-compat aliases
list_tools = _list_tools_impl
browse_tool = _browse_tool_impl
get_tool_section = _get_tool_section_impl


if __name__ == "__main__":
    print("\U0001f680 Accordance MCP Server running\u2026 (Ctrl+C to stop)")
    mcp.run(transport="stdio")
