"""Ground Truth 기준 초기 자본 누적 수익률 계산."""

from __future__ import annotations

from dataclasses import asdict, dataclass
from typing import Any


@dataclass
class LegPnl:
    """레그별 손익 (매수→매도 1쌍)."""

    leg_id: int
    buy_datetime: str
    sell_datetime: str
    buy_price: float
    sell_price: float
    cash_before: float
    cash_after: float
    leg_return_pct: float
    cumulative_return_pct: float
    btc_qty: float


def simulate_gt_pnl(
    legs: list[dict[str, Any]],
    initial_cash_krw: float = 400_000.0,
    fee_rate: float = 0.0005,
    min_order_krw: float = 5_000.0,
) -> dict[str, Any]:
    """GT 레그(1매수·1매도)를 순서대로 실행한 누적 수익률.

    - 초기 현금 전액 매수 → 전량 매도 반복 (복리)
    - 1단계 Ground Truth 벤치마크용

    Args:
        legs: GT legs 리스트.
        initial_cash_krw: 초기 원화.
        fee_rate: 편도 수수료율.
        min_order_krw: 최소 주문 금액.

    Returns:
        요약 + 레그별 손익 dict.
    """
    cash = float(initial_cash_krw)
    leg_pnls: list[LegPnl] = []
    skipped = 0

    for leg in legs:
        buy_price = float(leg["buy_price"])
        sell_price = float(leg["sell_price"])
        cash_before = cash

        if cash < min_order_krw:
            skipped += 1
            continue

        buy_fee = cash * fee_rate
        btc_bought = (cash - buy_fee) / buy_price
        cash = 0.0

        sell_gross = btc_bought * sell_price
        sell_fee = sell_gross * fee_rate
        cash = sell_gross - sell_fee

        leg_return = (cash - cash_before) / cash_before * 100.0
        cumulative = (cash - initial_cash_krw) / initial_cash_krw * 100.0

        leg_pnls.append(
            LegPnl(
                leg_id=int(leg["leg_id"]),
                buy_datetime=leg["buy_datetime"],
                sell_datetime=leg["sell_datetime"],
                buy_price=buy_price,
                sell_price=sell_price,
                cash_before=round(cash_before, 0),
                cash_after=round(cash, 0),
                leg_return_pct=round(leg_return, 2),
                cumulative_return_pct=round(cumulative, 2),
                btc_qty=round(btc_bought, 8),
            )
        )

    final_cash = cash
    total_return_pct = (final_cash - initial_cash_krw) / initial_cash_krw * 100.0

    period_from = leg_pnls[0].buy_datetime if leg_pnls else None
    period_to = leg_pnls[-1].sell_datetime if leg_pnls else None

    return {
        "initial_cash_krw": initial_cash_krw,
        "final_cash_krw": round(final_cash, 0),
        "total_pnl_krw": round(final_cash - initial_cash_krw, 0),
        "total_return_pct": round(total_return_pct, 2),
        "fee_rate": fee_rate,
        "legs_traded": len(leg_pnls),
        "legs_skipped": skipped,
        "period_from": period_from,
        "period_to": period_to,
        "leg_pnls": [asdict(x) for x in leg_pnls],
    }
