"""
Shared Catholic lectionary module.

Provides get_lectionary_readings() and get_lectionary_for_date_string()
for looking up Mass readings by date.

Data is sourced from https://catholic-resources.org/Lectionary/
(Felix Just, S.J.).  Psalm references in the data use LXX/Greek (Septuagint)
numbering (matching the USCCB lectionary).  They are AUTOMATICALLY converted
to MT/standard numbering by get_lectionary_readings() so they are compatible
with the bolls.life Bible API which stores NABRE with MT chapter numbers.
"""

from __future__ import annotations

import datetime as _dt
import re as _re
from typing import Dict, Tuple

from .canon import psalm_lxx_to_mt
from .lectionary_data import LECTIONARY_ALL as _LECTIONARY


# Regex to find the chapter number in a "Psalms NNN:..." reference.
_PSALM_REF_CHAPTER_RE = _re.compile(r"^(Psalms\s+)(\d+)([:;,\-].*)$")


def _convert_psalm_ref_lxx_to_mt(ref: str) -> str:
    """Convert a lectionary Psalm reference from LXX to MT chapter numbering.

    Handles references like:
        "Psalms 68:2-7"        -> "Psalms 69:2-7"
        "Psalms 68:10-11, 20-21" -> "Psalms 69:10-11, 20-21"

    Non-Psalm references pass through unchanged.
    """
    match = _PSALM_REF_CHAPTER_RE.match(ref)
    if not match:
        return ref
    prefix = match.group(1)
    lxx_chapter = int(match.group(2))
    suffix = match.group(3)
    mt_chapter = psalm_lxx_to_mt(lxx_chapter)
    return f"{prefix}{mt_chapter}{suffix}"


def get_lectionary_readings(target_date: _dt.date) -> Tuple[str, Dict[str, str]]:
    """Look up the Catholic lectionary readings for a given date.

    Psalm references are automatically converted from LXX (Catholic/lectionary)
    to MT/standard (Protestant) chapter numbering for compatibility with
    the bolls.life Bible API which stores all translations including NABRE
    with MT chapter numbers.

    Args:
        target_date: datetime.date object

    Returns:
        tuple of (season_string: str, readings: dict with keys
        "first", "psalm", "second" (optional), "gospel")
    """
    date_str = target_date.strftime("%Y-%m-%d")

    if date_str in _LECTIONARY:
        season, readings = _LECTIONARY[date_str]
        converted = dict(readings)
        if "psalm" in converted:
            converted["psalm"] = _convert_psalm_ref_lxx_to_mt(converted["psalm"])
        return season, converted

    # Fallback: date not in lectionary database
    year = target_date.year

    if year > 2027:
        season = f"Liturgical Year {year} (data not yet available)"
        return season, {
            "first": f"(See USCCB.org for {year} first reading)",
            "psalm": f"(See USCCB.org for {year} psalm)",
            "gospel": f"(See USCCB.org for {year} Gospel reading)",
        }

    # Approximate by calendar position for 2026 weekdays not yet covered.
    # 2027 weekday coverage is minimal — most weekdays will hit this fallback.
    pentecost = _dt.date(2026, 5, 24)
    trinity = _dt.date(2026, 5, 31)

    if trinity <= target_date <= _dt.date(2026, 11, 28):
        season = "Ordinary Time (Weekday, Year II)"
    elif pentecost < target_date < trinity:
        season = "Week after Pentecost"
    else:
        season = "Ordinary Time"

    return season, {
        "first": "(See USCCB.org for first reading)",
        "psalm": "(See USCCB.org for psalm)",
        "gospel": "(See USCCB.org for Gospel reading)",
    }


def get_lectionary_for_date_string(date_str: str):
    """Parse a date string (YYYY-MM-DD) and return lectionary readings.

    Args:
        date_str: Date string in YYYY-MM-DD format.

    Returns:
        tuple of (season_string, readings_dict) or None if invalid date
    """
    try:
        target = _dt.date.fromisoformat(date_str.strip())
    except (ValueError, TypeError, AttributeError):
        return None
    return get_lectionary_readings(target)
