import io

from openpyxl import load_workbook

from flyway.api.routes_print import sanitize
from flyway.printing.fill import fill
from flyway.printing.pdf import page_texts
from tests.api_client import NZ_15, make_client_product, make_load_in


def test_fill_keeps_unknown_placeholders_and_braces():
    assert fill("{{A}} {{B}} {x} {{ A }}", {"A": "1"}) == "1 {{B}} {x} {{ A }}"


def test_sanitize_strips_script_keeps_layout_and_placeholders():
    out = sanitize('<table border="1" style="width:100%"><tr><td onclick="x()">{{ClientName}}</td></tr></table>'
                   '<script>alert(1)</script>')
    assert "script" not in out and "onclick" not in out
    assert 'border="1"' in out and "{{ClientName}}" in out


def _set(api, type_, content):
    assert api.put(f"/api/templates/{type_}", json={"content": content}).status_code == 200


def test_load_in_check_sheet_pdf(admin_api):
    cid, pid = make_client_product(admin_api, name="A&B <Ltd>")
    li = make_load_in(admin_api, cid, pid, 3)
    _set(admin_api, "LoadInPrintHeader", "<p>Page {{PageNumber}} of {{PageCount}}</p>")
    _set(admin_api, "LoadInPrintCheckSheetBody", "<p>Client {{ClientName}} at {{Date}} {{Time}} AWB {{AwbNumber}}</p>")
    _set(admin_api, "LoadInPrintFooter", "<p>Food Quality Systems</p>")
    r = admin_api.get(f"/api/print/transfers/{li['id']}/check-sheet.pdf")
    assert r.status_code == 200 and r.headers["content-type"] == "application/pdf"
    pages = page_texts(r.content)
    assert len(pages) == 2
    assert "Page 1 of 2" in pages[0] and "Page 2 of 2" in pages[1]
    assert "Client A&B <Ltd> at 2/3/2026 3:00 PM AWB N/A" in pages[0]
    assert "Load-in Attachment" in pages[1] and "Food Quality Systems" in pages[1]


def test_table_and_attachment_pages_escape_values(admin_api):
    cid, pid = make_client_product(admin_api, name="<script>x</script>")
    li = make_load_in(admin_api, cid, pid, 3)
    html = admin_api.get(f"/api/print/transfers/{li['id']}/table").text
    assert "&lt;script&gt;" in html and "<script>x" not in html
    assert "Load-in Check Sheet" in html
    assert "Kiwi" in admin_api.get(f"/api/print/transfers/{li['id']}/attachment").text


def test_packing_slip_pdf_and_statistics(admin_api):
    cid, pid = make_client_product(admin_api)
    make_load_in(admin_api, cid, pid, 10)
    src = admin_api.get("/api/load-outs/sources", params={"client_id": cid}).json()[0]["id"]
    lo = admin_api.post("/api/load-outs", json={"client_id": cid, "code": "LO-1", "date": NZ_15, "to_rmp": "R9",
                                                "lines": [{"source_item_id": src, "quantity": 4}]}).json()
    admin_api.post(f"/api/load-outs/{lo['id']}/complete")
    admin_api.post("/api/load-outs/pack", json={"ids": [lo["id"]], "reference": "PS-1"})
    slip = admin_api.get("/api/packing-slips").json()["items"][0]
    _set(admin_api, "PackingSlipPrintBody", "<div>{{Reference}}</div>{{ProductList}}")
    _set(admin_api, "PackingSlipPrintCommonBlock1", "<p>Dispatcher</p>")
    r = admin_api.get(f"/api/print/packing-slips/{slip['id']}.pdf")
    text = page_texts(r.content)[0]
    assert "PS-1" in text and "Kiwi" in text and "Total 4 ctns." in text and "Dispatcher" in text
    x = admin_api.get(f"/api/print/packing-slips/{slip['id']}/statistics.xlsx")
    sheet = load_workbook(io.BytesIO(x.content)).active
    assert [sheet.cell(1, c).value for c in (1, 2, 3)] == ["Kiwi", "Batch code", "Quantity"]
    assert (sheet.cell(2, 2).value, sheet.cell(2, 3).value) == ("B1", "4 (4)")


def test_templates_admin_only(staff_api):
    assert staff_api.get("/api/templates").status_code == 403


def test_renderer_blocks_network_requests():
    import time

    from flyway.printing.pdf import render_pdf
    started = time.monotonic()
    pdf = render_pdf("", "", '<img src="http://10.255.255.1/x.png"><p>Body</p>')
    assert "Body" in page_texts(pdf)[0] and time.monotonic() - started < 15
