"""FDI unit tests — classifier, identifiers, planner, extractors, multidoc routes."""

from app.fdi.classify import classify_document
from app.fdi.extract import StructuredExtract
from app.fdi.extractors import apply_type_enrichment, enrich_invoice
from app.fdi.hybrid import _rrf, _tokenize
from app.fdi.identifiers import detect_id_query, extract_identifiers, normalize_id, validate_pan
from app.fdi.planner import build_plan, classify_fdi_intent
from app.fdi.schema import init_fdi_tables
from app.fdi.verify import format_money, score_confidence


def _base_extract(**kwargs) -> StructuredExtract:
    data = dict(
        doc_type="unknown",
        doc_type_confidence=0.5,
        source_type="pdf",
        ocr_used=False,
        parse_confidence=0.7,
        page_count=1,
        currency_primary="INR",
        period_start=None,
        period_end=None,
        issuer_name=None,
        holder_name=None,
        lines=[],
        assertions=[],
        identifiers=[],
        parties=[],
        document_text="",
    )
    data.update(kwargs)
    return StructuredExtract(**data)


def test_init_fdi_tables():
    init_fdi_tables()


def test_classify_doc_types():
    assert classify_document("UPI statement Paytm Total money paid", "Paytm_UPI.pdf").doc_type == "upi_statement"
    assert classify_document("Tax Invoice HSN Place of supply", "inv.pdf").doc_type == "invoice"
    assert classify_document("Form 16 TDS certificate", "form16.pdf").doc_type == "tax_document"
    assert classify_document("Consolidated Account Statement folio AMFI", "cas.pdf").doc_type == "mutual_fund_cas"
    assert classify_document("Balance Sheet Assets and Liabilities", "bs.pdf").doc_type == "balance_sheet"
    assert classify_document("random notes", "x.pdf").doc_type == "unknown"


def test_identifier_extraction_and_validation():
    text = """
    GSTIN: 29AAAAA0000A1Z5
    PAN: ABCDE1234F
    IFSC: HDFC0001234
    Invoice No: INV-2026-001
    UTR: 123456789012
    """
    # Use a syntactically valid-shaped GSTIN (checksum not fully validated beyond pattern)
    text = text.replace("29AAAAA0000A1Z5", "27AAPFU0939F1ZV")
    found = extract_identifiers(text)
    types = {f.id_type for f in found}
    assert "PAN" in types
    assert "IFSC" in types
    assert "INVOICE_NO" in types
    assert validate_pan("ABCDE1234F")
    assert not validate_pan("ABCDE12345")
    assert normalize_id("IFSC", "hdfc 0001234") == "HDFC0001234"


def test_detect_id_query():
    assert detect_id_query("what is the IFSC on this statement")[0] == "IFSC"
    got = detect_id_query("find invoice no INV-99")
    assert got and got[0] == "INVOICE_NO"


def test_planner_routes():
    assert classify_fdi_intent("how much did I spend")[0] == "aggregate_spend"
    assert classify_fdi_intent("what documents do I have")[0] == "corpus_inventory"
    assert classify_fdi_intent("compare my documents")[0] == "compare"
    assert classify_fdi_intent("reconcile invoices with bank")[0] == "reconcile"
    assert classify_fdi_intent("show duplicate payments")[0] == "duplicates"
    assert classify_fdi_intent("payment timeline by date")[0] == "timeline"
    assert classify_fdi_intent("what is my net pay")[0] == "metric_lookup"
    assert build_plan("how much did I spend").steps[0].tool in {"assertion", "sum_out"}
    assert build_plan("hi").steps[0].tool == "passthrough"
    assert any(s.tool == "lookup_id" for s in build_plan("what is the IFSC").steps)
    assert any(s.tool == "compare" for s in build_plan("compare my documents").steps)
    assert any(s.tool == "reconcile" for s in build_plan("reconcile invoices with bank").steps)


def test_invoice_enricher():
    base = _base_extract(
        doc_type="invoice",
        document_text="Tax Invoice\nInvoice No: INV-1001\nGrand Total: Rs. 12,500.00\n",
        parse_confidence=0.8,
    )
    enriched = enrich_invoice(base)
    kinds = {a.kind for a in enriched.assertions}
    assert "invoice_number" in kinds
    assert "invoice_total" in kinds
    total = next(a for a in enriched.assertions if a.kind == "invoice_total")
    assert total.value_numeric == 12500.0


def test_apply_type_enrichment_passthrough_unknown():
    base = _base_extract(doc_type="unknown", document_text="hello", parse_confidence=0.5)
    out = apply_type_enrichment(base)
    assert out.doc_type == "unknown"


def test_hybrid_helpers():
    assert _tokenize("Hello IFSC HDFC0001") == ["hello", "ifsc", "hdfc0001"]
    assert _rrf(1) > _rrf(2)


def test_verify_helpers():
    assert "₹" in format_money(1234.5, "INR")
    assert 0.5 <= score_confidence(parse_confidence=0.8, tool_fit=0.9, result_confidence=0.9) <= 1.0
