import io
import base64

import openpyxl

from report_v2 import build_report_v2


def sample_report(**overrides):
    report = {
        "name": "card_3way",
        "title": "Card 3-Way Recon",
        "business_name": "Acme Retail Group",
        "recon_date": "2026-06-09",
        "labels": {"internal_system": "POS", "location": "Store",
                   "location_plural": "Stores"},
        "report_config": {"location_summary": {"enabled": True},
                          "include_tier_breakdown": True},
        "stages": [
            {
                "stage": "bank_card_vs_gateway",
                "display_name": "Bank Card vs Gateway",
                "sheet_matched": "BankCard-GW-Matched",
                "sheet_unmatched": "BankCard-GW-Unmatched",
                "sheet_unmatched_b": "GW-NoSettlement",
                "matched_rows": [
                    {"card_last4": "1111", "amount": 500.0, "match_tier": "exact-4key",
                     "location": "Store-A", "transaction_id": "TXN1"},
                    {"card_last4": "2222", "amount": 750.0, "match_tier": "3key",
                     "location": "Store-B", "transaction_id": "TXN2"},
                ],
                "unmatched_a_rows": [
                    {"card_last4": "3333", "amount": 900.0, "location": "Store-A"},
                ],
                "unmatched_b_rows": [
                    {"card_last4": "4444", "amount": 120.0},
                ],
            },
            {
                "stage": "internal_vs_bank_card",
                "display_name": "Internal vs Matched Bank Card",
                "sheet_matched": "Internal-Matched",
                "sheet_unmatched": "Internal-Unmatched",
                "sheet_unmatched_b": None,
                "matched_rows": [],
                "unmatched_a_rows": [],
                "unmatched_b_rows": [],
            },
        ],
    }
    report.update(overrides)
    return report


def render(report):
    b64 = build_report_v2(report)
    return openpyxl.load_workbook(io.BytesIO(base64.b64decode(b64)))


def test_sheets_created_from_stage_config():
    wb = render(sample_report())
    assert wb.sheetnames[0] == "Summary"
    for name in ["BankCard-GW-Matched", "BankCard-GW-Unmatched", "GW-NoSettlement",
                 "Internal-Matched", "Internal-Unmatched"]:
        assert name in wb.sheetnames


def test_matched_sheet_has_priority_columns_first_and_data():
    wb = render(sample_report())
    ws = wb["BankCard-GW-Matched"]
    headers = [c.value for c in ws[1]]
    assert headers[0] == "Match Tier"
    assert headers[1] == "Location"
    assert ws.max_row == 3  # header + 2 rows
    tiers = {ws.cell(row=r, column=1).value for r in (2, 3)}
    assert tiers == {"exact-4key", "3key"}


def test_empty_stage_sheets_render_no_data():
    wb = render(sample_report())
    assert wb["Internal-Matched"]["A1"].value == "No data"


def test_summary_business_name_and_stage_totals():
    wb = render(sample_report())
    ws = wb["Summary"]
    assert ws["A1"].value == "Acme Retail Group"

    values = [[c.value for c in row] for row in ws.iter_rows()]
    flat = [v for row in values for v in row if v is not None]

    assert "Bank Card vs Gateway" in flat
    # tier breakdown rendered
    assert any("exact-4key" in str(v) for v in flat)
    assert any("3key" in str(v) for v in flat)


def test_summary_uses_tenant_location_label():
    wb = render(sample_report())
    ws = wb["Summary"]
    flat = [c.value for row in ws.iter_rows() for c in row if c.value is not None]
    # Label from business profile ("Store"), not hardcoded hospital vocabulary
    assert any(str(v).startswith("Store-wise") for v in flat)
    assert "Store" in flat
    assert not any("Unit" == v for v in flat)


def test_location_summary_can_be_disabled():
    report = sample_report(report_config={"location_summary": {"enabled": False},
                                          "include_tier_breakdown": False})
    wb = render(report)
    ws = wb["Summary"]
    flat = [c.value for row in ws.iter_rows() for c in row if c.value is not None]
    assert not any(str(v).startswith("Store-wise") for v in flat)
    assert not any("↳ tier" in str(v) for v in flat)


def test_duplicate_sheet_names_are_deduplicated():
    report = sample_report()
    report["stages"][1]["sheet_matched"] = "BankCard-GW-Matched"
    wb = render(report)
    matched_like = [n for n in wb.sheetnames if n.startswith("BankCard-GW-Matched")]
    assert len(matched_like) == 2


def test_column_union_across_rows():
    report = sample_report()
    report["stages"][0]["matched_rows"] = [
        {"amount": 1, "only_in_first": "x", "match_tier": "t"},
        {"amount": 2, "only_in_second": "y", "match_tier": "t"},
    ]
    wb = render(report)
    headers = [c.value for c in wb["BankCard-GW-Matched"][1]]
    assert "Only In First" in headers and "Only In Second" in headers
