"""test_idp.py — `pytest -q` (offline). Success criteria for the IDP pipeline."""
from __future__ import annotations

from idp import SAMPLE_DOCS, IDPPipeline, FakeExtractor, classify
from validation import (date_not_expired, iban_is_valid, normalize_digits,
                        statement_balance_consistent)


# --- validators (real algorithms) ------------------------------------------
def test_iban_mod97():
    assert iban_is_valid("AE07 0331 2345 6789 0123 456") is True
    assert iban_is_valid("AE07 0331 2345 6789 0123 457") is False   # one digit off
    assert iban_is_valid("GB82 WEST 1234 5698 7654 32") is True     # letters mapped


def test_balance_math():
    assert statement_balance_consistent(1000.0, [9000.0, -85.5, -8000.0], 1914.5) is True
    assert statement_balance_consistent(1000.0, [9000.0, -85.5, -9000.0], 1914.5) is False


def test_eastern_numeral_normalization():
    assert normalize_digits("٧٨٤") == "784"
    assert iban_is_valid(normalize_digits("AE٠٧0331234567890123456")) is True


def test_expiry():
    assert date_not_expired("2028-03-01") is True
    assert date_not_expired("2024-01-01") is False


# --- pipeline behavior ------------------------------------------------------
def test_clean_statement_is_straight_through():
    pipe = IDPPipeline()
    doc = pipe.process(SAMPLE_DOCS["statement_clean"])
    assert doc.straight_through is True
    assert doc.validation["AccountIBAN"] is True
    assert doc.validation["Transactions"] is True


def test_bad_row_goes_to_review():
    pipe = IDPPipeline()
    doc = pipe.process(SAMPLE_DOCS["statement_bad_row"])
    assert doc.straight_through is False
    assert "Transactions" in doc.review_fields       # low confidence AND failed math


def test_low_confidence_and_expired_id_reviewed():
    pipe = IDPPipeline()
    doc = pipe.process(SAMPLE_DOCS["id_lowconf"])
    assert doc.straight_through is False
    assert "FullName" in doc.review_fields            # blurry -> low confidence
    assert doc.validation["Expiry"] is False          # expired -> validation fail


def test_stp_rate_and_audit():
    pipe = IDPPipeline()
    for raw in SAMPLE_DOCS.values():
        pipe.process(raw)
    # 2 of 4 clean -> 50% straight-through.
    assert pipe.stp_rate() == 0.5
    # audit records the pipeline stages
    doc = pipe.store[0]
    steps = [a["step"] for a in doc.audit]
    assert steps[:3] == ["classify", "extract", "confidence_gate"]


def test_classify_routes_by_type():
    assert classify(SAMPLE_DOCS["emirates_id"]) == "id_document"
    assert classify(SAMPLE_DOCS["statement_clean"]) == "bank_statement"
