from __future__ import annotations

import logging
from typing import Any
from decimal import Decimal, ROUND_HALF_UP

logger = logging.getLogger(__name__)

class IpcCalculatorMixin:
    """Tính toán Phụ lục 03a IPC (Interim Payment Certificate)."""

    def calculate_ipc_03a(
        self,
        project_id: str,
        stage_number: int,
        completed_value_vnd: Decimal,
        advance_pct: Decimal = Decimal("10.0"),
        retention_pct: Decimal = Decimal("5.0"),
    ) -> dict[str, Any]:
        """
        Tính toán giá trị thanh toán đợt (Phụ lục 03a) lũy kế kỳ trước và kỳ này.
        """
        # Fetch cumulative previous values from DB
        sql_prev = """
            SELECT COALESCE(SUM(completed_value_vnd), 0) as prev_completed,
                   COALESCE(SUM(advance_deduction_vnd), 0) as prev_advance,
                   COALESCE(SUM(retention_deduction_vnd), 0) as prev_retention,
                   COALESCE(SUM(net_payment_vnd), 0) as prev_net
            FROM erp_dossier_ipcs
            WHERE project_id = %s AND stage_number < %s AND status = 'APPROVED'
        """
        prev_completed = Decimal("0")
        prev_advance = Decimal("0")
        prev_retention = Decimal("0")
        
        # We need a db connection here. Assume `self` has `get_connection()` if it's BasePostgresClient
        try:
            with self.get_connection() as conn, conn.cursor() as cur:
                cur.execute(sql_prev, (project_id, stage_number))
                row = cur.fetchone()
                if row:
                    prev_completed = Decimal(str(row["prev_completed"]))
                    prev_advance = Decimal(str(row["prev_advance"]))
                    prev_retention = Decimal(str(row["prev_retention"]))
        except Exception as e:
            logger.warning(f"Không thể tra cứu lũy kế kỳ trước: {e}")

        # Values for THIS stage
        current_completed = Decimal(str(completed_value_vnd)).quantize(Decimal("0.0000"), rounding=ROUND_HALF_UP)
        current_advance = (current_completed * advance_pct / Decimal("100")).quantize(Decimal("0.0000"), rounding=ROUND_HALF_UP)
        current_retention = (current_completed * retention_pct / Decimal("100")).quantize(Decimal("0.0000"), rounding=ROUND_HALF_UP)
        current_net = current_completed - current_advance - current_retention

        # Cumulative to date
        total_completed = prev_completed + current_completed
        total_advance = prev_advance + current_advance
        total_retention = prev_retention + current_retention
        total_net = total_completed - total_advance - total_retention

        return {
            "project_id": project_id,
            "stage_number": stage_number,
            "period": {
                "completed_value_vnd": str(current_completed),
                "advance_deduction_vnd": str(current_advance),
                "retention_deduction_vnd": str(current_retention),
                "net_payment_vnd": str(current_net),
            },
            "cumulative_previous": {
                "completed_value_vnd": str(prev_completed),
                "advance_deduction_vnd": str(prev_advance),
                "retention_deduction_vnd": str(prev_retention),
            },
            "cumulative_to_date": {
                "completed_value_vnd": str(total_completed),
                "advance_deduction_vnd": str(total_advance),
                "retention_deduction_vnd": str(total_retention),
                "net_payment_vnd": str(total_net),
            },
            "status": "QS_REVIEWED"
        }
