"""Handle a TA1 Interchange Acknowledgment file (SP27 Task 3).

Lifted verbatim from ``scheduler.py:_handle_ta1``. The handler owns
its own DB session, dispatches to ``parse_ta1_text``, persists the
interchange ack row in ``ta1_acks``, and returns a
``(parser_used, claim_count)`` tuple.

Unlike the 999 handler, TA1 is envelope-only — there is one TA1 per
ISA/IEA interchange, no set-level (AK2) or claim-level matching.
The claim_count is always 1 (one TA1 ack row per file).

The actor tag is implicit (no audit event here — TA1 doesn't tag
anything in the activity log; it's an infrastructure-level ack).
"""
from __future__ import annotations

import json
import logging

from cyclone import db
from cyclone.parsers.exceptions import CycloneParseError
from cyclone.parsers.parse_ta1 import parse_ta1_text
from cyclone.store import store as cycl_store

log = logging.getLogger(__name__)


def handle(
    text: str,
    source_file: str,
) -> tuple[str, int]:
    """Parse a TA1, persist the interchange ack row.

    Args:
        text: Raw TA1 document bytes (decoded).
        source_file: Filename the TA1 came from. Used for audit
            attribution; the ``batches.id`` for TA1 rows is derived
            internally from the parsed envelope's control number
            (``TA1-{ICN}``).

    Returns:
        ``(parser_used, claim_count)`` tuple. TA1 always returns
        ``claim_count=1`` (one TA1 ack row per interchange file).

    Raises:
        ValueError: on parser-level failure (wraps CycloneParseError).

    SP25: the store (``cyclone.store.acks.add_ta1_ack``) owns the
    publish-from-store contract; the handler no longer needs an
    ``event_bus`` kwarg.
    """
    try:
        result = parse_ta1_text(text, input_file=source_file)
    except CycloneParseError as exc:
        raise ValueError(f"TA1 parse error: {exc}") from exc

    with db.SessionLocal()() as session:
        cycl_store.add_ta1_ack(
            source_batch_id=result.source_batch_id,
            control_number=result.ta1.control_number,
            interchange_date=result.ta1.interchange_date,
            interchange_time=result.ta1.interchange_time,
            ack_code=result.ta1.ack_code,
            note_code=result.ta1.note_code,
            ack_generated_date=result.ta1.ack_generated_date,
            sender_id=result.envelope.sender_id,
            receiver_id=result.envelope.receiver_id,
            raw_json=json.loads(result.model_dump_json()),
        )
        session.commit()

    return ("parse_ta1", 1)
