from datetime import date, timedelta
from decimal import Decimal

from app.modules.financial.application.financial_war_room_service import FinancialWarRoomService


class MockPostgresClient:
    def fetch_planned_transactions(self, start_date: date, end_date: date):
        # Return some mock transactions
        return [
            {
                "transaction_date": start_date + timedelta(days=5),
                "transaction_type": "stage_payment",
                "direction": "inflow",
                "amount": Decimal("650000000.0000"),
            },
            {
                "transaction_date": start_date + timedelta(days=10),
                "transaction_type": "supplier_payment",
                "direction": "outflow",
                "amount": Decimal("5000000000.0000"),  # Big outflow
            },
        ]


def test_financial_war_room_stress_test_no_delay():
    mock_client = MockPostgresClient()
    service = FinancialWarRoomService(postgres_client=mock_client)

    # Base case, current cash is 4.85B
    # Inflow 650M on day 5 -> 5.5B
    # Outflow 5B on day 10 -> 0.5B
    # Never goes below 0
    data = service.get_war_room_summary(
        as_of_date=date(2026, 1, 1), client_delay_days=0
    )

    assert data.cashflow_runway.liquidity_risk_alert is False
    assert data.cashflow_runway.lowest_balance == Decimal("500000000.0000")


def test_financial_war_room_stress_test_with_delay():
    mock_client = MockPostgresClient()
    service = FinancialWarRoomService(postgres_client=mock_client)

    # Stress test: 30 days delay
    # Inflow shifted to day 35
    # Outflow on day 10 is 5B
    # current_cash is 4.85B
    # On day 10, balance becomes 4.85B - 5B = -150M -> Liquidity Risk!
    data = service.get_war_room_summary(
        as_of_date=date(2026, 1, 1), client_delay_days=30
    )

    assert data.cashflow_runway.liquidity_risk_alert is True
    assert data.cashflow_runway.lowest_balance == Decimal("-150000000.0000")
    assert data.cashflow_runway.risk_date == "2026-01-11"  # day 10
    assert (
        data.cashflow_runway.net_runway_days == 9
    )  # Day 10 is index 10, so runway is 9 days
