"""G-spread (`fuggers_py.analytics.spreads.gspread`)."""

from __future__ import annotations

from dataclasses import dataclass
from decimal import Decimal

from fuggers_py.bonds.traits import Bond
from fuggers_py.bonds.types import Tenor
from fuggers_py.core.types import Date

from .benchmark import BenchmarkSpec, BenchmarkKind, _to_decimal
from .government_curve import GovernmentCurve


def g_spread(bond_yield: object, benchmark_yield: object) -> Decimal:
    by = _to_decimal(bond_yield)
    gy = _to_decimal(benchmark_yield)
    return (by - gy) * Decimal(10_000)


def g_spread_with_benchmark(
    bond_yield: object,
    curve: GovernmentCurve,
    maturity: Tenor | Date,
    *,
    benchmark: BenchmarkSpec | None = None,
) -> Decimal:
    if benchmark is None:
        benchmark = BenchmarkSpec.interpolated()
    if benchmark.kind is BenchmarkKind.EXPLICIT and benchmark.explicit_yield is not None:
        bench_yield = benchmark.explicit_yield
    else:
        if isinstance(maturity, Tenor):
            bench_yield = curve.yield_for_tenor(maturity, spec=benchmark)
        else:
            bench_yield = curve.yield_for_date(maturity, spec=benchmark)
    return g_spread(bond_yield, bench_yield)


@dataclass(frozen=True, slots=True)
class GSpreadCalculator:
    curve: GovernmentCurve

    def spread_bps(
        self,
        bond: Bond,
        bond_yield: object,
        *,
        benchmark: BenchmarkSpec | None = None,
    ) -> Decimal:
        maturity = bond.maturity_date()
        return g_spread_with_benchmark(bond_yield, self.curve, maturity, benchmark=benchmark)


__all__ = ["GSpreadCalculator", "g_spread", "g_spread_with_benchmark"]
