from __future__ import annotations

"""Weighted Average Cost helpers.

Weighted Average Cost (WAC) is the MVP internal performance method for this
system. It is deterministic and adequate for portfolio performance reporting:
buys increase quantity and cost basis, buy fees increase cost basis, sells
reduce cost basis proportionally, and realized P&L is computed against average
cost.

This is **not** a complete tax method. It intentionally does not implement
FIFO/LIFO/tax-lot accounting. The ledger keeps transactions granular so a later
tax-lot module can be added without replacing the transaction foundation.
"""

from dataclasses import dataclass
from decimal import Decimal, ROUND_HALF_UP

MONEY = Decimal("0.01")
QTY = Decimal("0.00000001")


def qmoney(value: Decimal) -> Decimal:
    return value.quantize(MONEY, rounding=ROUND_HALF_UP)


def qqty(value: Decimal) -> Decimal:
    return value.quantize(QTY, rounding=ROUND_HALF_UP).normalize()


@dataclass
class WeightedAverageLot:
    quantity: Decimal = Decimal("0")
    cost_basis_original: Decimal = Decimal("0")
    cost_basis_chf: Decimal = Decimal("0")
    realized_pnl_chf: Decimal = Decimal("0")

    @property
    def average_cost_original(self) -> Decimal | None:
        if self.quantity == 0:
            return None
        return (self.cost_basis_original / self.quantity).quantize(Decimal("0.00000001"), rounding=ROUND_HALF_UP).normalize()

    @property
    def average_cost_chf(self) -> Decimal | None:
        if self.quantity == 0:
            return None
        return (self.cost_basis_chf / self.quantity).quantize(Decimal("0.00000001"), rounding=ROUND_HALF_UP).normalize()

    def buy(self, quantity: Decimal, cost_original: Decimal, cost_chf: Decimal) -> None:
        if quantity <= 0:
            raise ValueError("buy quantity must be > 0")
        self.quantity += quantity
        self.cost_basis_original += cost_original
        self.cost_basis_chf += cost_chf

    def sell(self, quantity: Decimal, proceeds_chf: Decimal) -> None:
        if quantity <= 0:
            raise ValueError("sell quantity must be > 0")
        if self.quantity <= 0 or quantity > self.quantity:
            raise ValueError("sell quantity exceeds current position")
        ratio = quantity / self.quantity
        removed_original = self.cost_basis_original * ratio
        removed_chf = self.cost_basis_chf * ratio
        self.quantity -= quantity
        self.cost_basis_original -= removed_original
        self.cost_basis_chf -= removed_chf
        self.realized_pnl_chf += proceeds_chf - removed_chf
        if self.quantity == 0:
            self.cost_basis_original = Decimal("0")
            self.cost_basis_chf = Decimal("0")
