"""ReportLayoutResponse — filters, insight, consolidation and hierarchy sections
built via the accumulation API and serialized by get_report_data().
"""

from boh.report.layout import ReportTitle, ReportValue, ReportValueFormatters
from boh.report.layout.report_layout_response import ReportLayoutResponse


# --- filters --------------------------------------------------------------


def test_filter_title_appears_in_filters_section():
    r = ReportLayoutResponse()
    r.set_filter_title(ReportTitle("$PERIOD"))

    assert r.get_report_data()["filters"]["title"] == "$PERIOD"


def test_filter_with_params_resolves_to_dict():
    r = ReportLayoutResponse()
    r.add_filter(ReportTitle("$DATE_RANGE", ["2026-01-01", "2026-01-31"]))

    fields = r.get_report_data()["filters"]["fields"]
    assert fields[0]["title"] == {"text": "$DATE_RANGE", "params": ["2026-01-01", "2026-01-31"]}


def test_multiple_filters_are_ordered_by_insertion():
    r = ReportLayoutResponse()
    r.add_filter(ReportTitle("$FIRST"))
    r.add_filter(ReportTitle("$SECOND"))

    fields = r.get_report_data()["filters"]["fields"]
    assert fields[0]["title"] == "$FIRST"
    assert fields[1]["title"] == "$SECOND"


def test_filters_are_none_when_none_added():
    r = ReportLayoutResponse()

    assert r.get_report_data()["filters"] is None


# --- insight --------------------------------------------------------------


def test_insight_is_built_from_accumulated_options():
    r = ReportLayoutResponse()
    r.add_insight_option_value("store_a", 80.0, "Store A")
    r.add_insight_option_value("store_b", 20.0, "Store B")

    insight = r.get_report_data()["insight"]
    assert insight is not None
    assert insight["value"]["type"] == "percent"


def test_insight_uses_explicit_value_when_set():
    r = ReportLayoutResponse()
    r.set_insight_value(75.0)

    insight = r.get_report_data()["insight"]
    assert insight["value"] == {"value": 75.0, "type": "percent"}


def test_insight_is_none_when_no_options_or_value():
    r = ReportLayoutResponse()

    assert r.get_report_data()["insight"] is None


def test_insight_color_is_ok_when_best_option_is_above_threshold():
    r = ReportLayoutResponse()
    r.add_insight_option_value("a", 80.0)
    r.add_insight_option_value("b", 20.0)
    r.set_insight_threshold(70.0, "ok")

    assert r.get_report_data()["insight"]["type"] == "ok"


def test_insight_color_is_alert_when_best_option_is_below_threshold():
    r = ReportLayoutResponse()
    r.add_insight_option_value("a", 30.0)
    r.add_insight_option_value("b", 70.0)
    r.set_insight_threshold(80.0, "ok")

    assert r.get_report_data()["insight"]["type"] == "alert"


# --- consolidation --------------------------------------------------------


def test_consolidation_option_appears_in_report_data():
    r = ReportLayoutResponse()
    r.set_consolidation_option(
        "total",
        title=ReportTitle("$TOTAL"),
        initial_value=ReportValue(100.0, ReportValueFormatters.CURRENCY),
        line=0,
    )

    fields = r.get_report_data()["consolidation"]["fields"]
    assert fields[0][0]["title"] == "$TOTAL"
    assert fields[0][0]["value"] == {"value": 100.0, "type": "currency"}


def test_consolidation_accumulates_values_across_calls():
    r = ReportLayoutResponse()
    r.set_consolidation_option(
        "total",
        title=ReportTitle("$TOTAL"),
        initial_value=ReportValue(100.0, ReportValueFormatters.CURRENCY),
        line=0,
    )
    r.add_consolidation_option_value("total", 50.0)

    fields = r.get_report_data()["consolidation"]["fields"]
    assert fields[0][0]["value"]["value"] == 150.0


def test_consolidation_is_none_when_no_options_set():
    r = ReportLayoutResponse()

    assert r.get_report_data()["consolidation"] is None


# --- hierarchy ------------------------------------------------------------


def test_hierarchy_node_appears_in_report_data():
    r = ReportLayoutResponse()
    r.add_hierarchy_header(ReportTitle("$STORE"), "store")
    r.set_hierarchy_node_data("n1", "Store A")
    r.add_hierarchy_node_value("n1", "store", ReportValue(1000.0, ReportValueFormatters.CURRENCY))

    hierarchy = r.get_report_data()["hierarchy"]
    assert hierarchy["headers"][0] == {"title": "$STORE", "id": "store"}
    assert hierarchy["data"][0]["name"] == "Store A"


def test_hierarchy_accumulates_values_to_parent_node():
    r = ReportLayoutResponse()
    r.set_hierarchy_node_data("parent", "Region")
    r.set_hierarchy_node_data("child", "Store A", parent_node_id="parent")
    r.add_hierarchy_node_value("child", "sales", ReportValue(500.0))

    data = r.get_report_data()["hierarchy"]["data"]
    parent = next(n for n in data if n["name"] == "Region")
    assert parent["values"]["sales"] == 500.0


def test_hierarchy_is_none_when_no_nodes_set():
    r = ReportLayoutResponse()

    assert r.get_report_data()["hierarchy"] is None


# --- source data ----------------------------------------------------------


def test_source_data_appears_in_report_data_when_added():
    r = ReportLayoutResponse()
    r.add_source_data(
        title=ReportTitle("$GENERATED_ON"),
        value=ReportValue("2026-05-28T10:00:00", ReportValueFormatters.DATETIME),
    )

    source = r.get_report_data()["source_data"]
    assert source[0]["title"] == "$GENERATED_ON"
    assert source[0]["value"] == {"value": "2026-05-28T10:00:00", "type": "datetime"}


def test_source_data_is_none_when_none_added():
    r = ReportLayoutResponse()

    assert r.get_report_data()["source_data"] is None
