"""Tests for cross-module metric extraction.

These tests verify that metric calculations are shared across
report generators via the metrics module, producing consistent
and correct results.

DO NOT modify these tests.
"""

import pytest


# -- Shared metrics must exist in metrics module --------------------------


class TestSharedMetrics:

    def test_percentage_change_basic(self):
        from src.metrics import percentage_change
        assert percentage_change(100, 150) == 50.0

    def test_percentage_change_zero_base(self):
        from src.metrics import percentage_change
        result = percentage_change(0, 100)
        assert result == float("inf")

    def test_percentage_change_both_zero(self):
        from src.metrics import percentage_change
        assert percentage_change(0, 0) == 0.0

    def test_moving_average_basic(self):
        from src.metrics import moving_average
        result = moving_average([10, 20, 30, 40], 3)
        assert result == [20.0, 30.0]

    def test_moving_average_short_data(self):
        from src.metrics import moving_average
        assert moving_average([10, 20], 3) == []

    def test_detect_outliers_finds_extreme(self):
        from src.metrics import detect_outliers
        data = [10, 11, 12, 100, 11, 10]
        outliers = detect_outliers(data, 2.0)
        assert 100 in outliers
        assert 10 not in outliers


# -- Individual reports produce correct results ---------------------------


class TestSalesReport:

    def test_generate_correct_change(self):
        from src.sales_report import generate
        result = generate(150, 100, [10, 20, 30])
        assert result["change"].value == 50.0

    def test_generate_trend(self):
        from src.sales_report import generate
        result = generate(100, 100, [10, 20, 30, 40])
        assert result["trend"] == [20.0, 30.0]


class TestInventoryReport:

    def test_generate_zero_previous_stock(self):
        from src.inventory_report import generate
        result = generate(100, 0, [10, 20, 30])
        assert result["change"].value == float("inf")

    def test_generate_correct_trend(self):
        from src.inventory_report import generate
        result = generate(100, 50, [10, 20, 30, 40])
        assert result["trend"] == [20.0, 30.0]


class TestDashboard:

    def test_aggregate_trend_uses_window_3(self):
        from src.dashboard import aggregate
        sections = {
            "test": {"current": 100, "previous": 50, "daily": [10, 20, 30, 40]},
        }
        result = aggregate(sections)
        assert result["test"]["trend"] == [20.0, 30.0]


# -- Reports must produce consistent results for same data ---------------


class TestConsistency:

    def test_same_data_same_change(self):
        from src.sales_report import generate as sales_gen
        from src.inventory_report import generate as inv_gen
        from src.dashboard import aggregate

        sales = sales_gen(150, 100, [10, 20, 30])
        inv = inv_gen(150, 100, [10, 20, 30])
        dash = aggregate(
            {"s": {"current": 150, "previous": 100, "daily": [10, 20, 30]}}
        )

        assert sales["change"].value == inv["change"].value
        assert sales["change"].value == dash["s"]["change"].value

    def test_same_data_same_trend(self):
        from src.sales_report import generate as sales_gen
        from src.inventory_report import generate as inv_gen

        sales = sales_gen(100, 100, [10, 20, 30, 40])
        inv = inv_gen(100, 100, [10, 20, 30, 40])

        assert sales["trend"] == inv["trend"]
