"""Portfolio types for fixed-income research."""

from __future__ import annotations

from dataclasses import dataclass, field
from decimal import Decimal

from fuggers_py.bonds.types import CreditRating, RatingInfo, Sector, SectorInfo, Seniority, SeniorityInfo
from fuggers_py.core.types import Currency

from .cash import CashPosition
from .classification import Classification
from .config import AnalyticsConfig
from .holding import Holding, HoldingAnalytics, HoldingBuilder, Position, PositionAnalytics
from .maturity import MaturityBucket
from .weighting import WeightingMethod


@dataclass(frozen=True, slots=True)
class RatingBucket:
    label: str
    ratings: tuple[CreditRating, ...]


@dataclass(frozen=True, slots=True)
class BucketResult:
    label: str
    clean_pv: Decimal
    dirty_pv: Decimal
    dv01: Decimal
    weight: Decimal = Decimal(0)
    market_value: Decimal = Decimal(0)
    average_ytm: Decimal | None = None
    average_duration: Decimal | None = None
    average_spread: Decimal | None = None
    holding_count: int = 0


@dataclass(frozen=True, slots=True)
class StressResult:
    base_dirty_pv: Decimal
    stressed_dirty_pv: Decimal
    actual_change: Decimal
    dv01_approximation: Decimal
    scenario_name: str | None = None
    breakdown: dict[str, Decimal] = field(default_factory=dict)

    @property
    def shocked_pv(self) -> Decimal:
        return self.stressed_dirty_pv

    @property
    def pv_change(self) -> Decimal:
        return self.actual_change


@dataclass(frozen=True, slots=True)
class PortfolioMetrics:
    clean_pv: Decimal
    dirty_pv: Decimal
    accrued: Decimal
    duration: Decimal
    convexity: Decimal
    dv01: Decimal
    weights: dict[str, Decimal]
    currency: Currency
    current_yield: Decimal = Decimal(0)
    ytm: Decimal = Decimal(0)
    ytw: Decimal = Decimal(0)
    ytc: Decimal = Decimal(0)
    best_yield: Decimal = Decimal(0)
    z_spread: Decimal = Decimal(0)
    oas: Decimal = Decimal(0)
    g_spread: Decimal = Decimal(0)
    i_spread: Decimal = Decimal(0)
    asw: Decimal = Decimal(0)
    best_spread: Decimal = Decimal(0)
    spread_duration: Decimal = Decimal(0)
    cs01: Decimal = Decimal(0)
    liquidity_score: Decimal = Decimal(0)
    key_rate_profile: dict[str, Decimal] = field(default_factory=dict)
    total_market_value: Decimal = Decimal(0)
    total_dirty_market_value: Decimal = Decimal(0)
    total_accrued_interest: Decimal = Decimal(0)
    cash_value: Decimal = Decimal(0)
    holding_count: int = 0
    priced_count: int = 0
    coverage_count: int = 0
    modified_duration: Decimal = Decimal(0)
    effective_duration: Decimal = Decimal(0)
    macaulay_duration: Decimal = Decimal(0)
    effective_convexity: Decimal = Decimal(0)
    weighted_average_maturity: Decimal = Decimal(0)
    weighted_average_coupon: Decimal = Decimal(0)


__all__ = [
    "AnalyticsConfig",
    "BucketResult",
    "CashPosition",
    "Classification",
    "CreditRating",
    "Holding",
    "HoldingAnalytics",
    "HoldingBuilder",
    "MaturityBucket",
    "PortfolioMetrics",
    "Position",
    "PositionAnalytics",
    "RatingBucket",
    "RatingInfo",
    "Sector",
    "SectorInfo",
    "Seniority",
    "SeniorityInfo",
    "StressResult",
    "WeightingMethod",
]
