from decimal import Decimal

from app.models.four_pillars_schemas import IPC03aExportRequest
from app.modules.financial.application.four_pillars.pillar_construction import ConstructionPillarMixin
from app.modules.core.application.ipc_exporter_service import IPCExporterService


class MockPostgresClient:
    def __init__(self, project_detail=None):
        self.project_detail = project_detail or {}
        self.transactions = []

    def get_project_detail(self, project_code):
        return self.project_detail

    def create_ipc_financial_transactions(
        self,
        project_id,
        company_id,
        period_number,
        net_payable,
        retention_amount,
        advance_recovery_amount,
    ):
        self.transactions.append(
            {
                "project_id": project_id,
                "company_id": company_id,
                "period_number": period_number,
                "net_payable": net_payable,
                "retention_amount": retention_amount,
                "advance_recovery_amount": advance_recovery_amount,
            }
        )
        return ["tx_1", "tx_2", "tx_3"]


class MockFourPillarsService(ConstructionPillarMixin):
    def __init__(self, postgres_client=None):
        self.postgres_client = postgres_client


def test_ipc_exporter_service_dynamic_rates():
    project_detail = {
        "id": "proj-123",
        "company_id": "comp-123",
        "advance_payment_percent": 15.0,
        "retention_percent": 3.0,
    }
    mock_client = MockPostgresClient(project_detail)
    service = IPCExporterService(postgres_client=mock_client)

    response = service.generate_ipc_03a(
        project_code="DA-KM-BENKEM-2025-2026", period_number=3
    )

    assert response.advance_recovery_rate_pct == Decimal("15.0000")
    assert response.retention_rate_pct == Decimal("3.0000")

    assert len(mock_client.transactions) == 1
    tx = mock_client.transactions[0]
    assert tx["project_id"] == "proj-123"
    assert tx["company_id"] == "comp-123"
    assert tx["period_number"] == 3


def test_pillar_construction_dynamic_rates():
    project_detail = {
        "id": "proj-123",
        "company_id": "comp-123",
        "advance_payment_percent": 20.0,
        "retention_percent": 4.0,
    }
    mock_client = MockPostgresClient(project_detail)
    service = MockFourPillarsService(postgres_client=mock_client)

    request = IPC03aExportRequest(
        project_code="DA-KM-BENKEM-2025-2026",
        period_number=4,
        advance_recovery_rate_pct=Decimal("10.0"),  # Should be overridden by DB
        retention_rate_pct=Decimal("5.0"),  # Should be overridden by DB
    )

    response = service.generate_ipc_document(request)

    # We can check the amounts. The mock data has period_work_val = 338.5M
    # If advance is 20%, it's 67.7M. If retention is 4%, it's 13.54M
    # Just check if transactions were created
    assert len(mock_client.transactions) == 1
    tx = mock_client.transactions[0]
    assert tx["project_id"] == "proj-123"
    assert tx["company_id"] == "comp-123"
    assert tx["period_number"] == 4
