"""
Option C 2차 목표(+1000%) 검증 — hybrid tier 포트폴리오 WF·슬리피지·Go/No-Go.
"""

from __future__ import annotations

from typing import Any

import pandas as pd

from config import (
    GT_INITIAL_CASH_KRW,
    LIVE_SLIPPAGE_PCT,
    SIM_HYBRID_MAX_MDD_PCT,
    SIM_HYBRID_PORTFOLIO_WF_MIN_RATIO,
    SIM_OPTION_C_MIN_GT_CAPTURE,
    SIM_OPTION_C_PHASE2_FEE_STRESS_RATIO,
    SIM_OPTION_C_PHASE2_TARGET_PNL_PCT,
)
from deepcoin.ground_truth.gt_allocation import simulate_portfolio_summary


def apply_slippage_to_trades(
    trades: list[dict[str, Any]],
    slippage_pct: float = LIVE_SLIPPAGE_PCT,
) -> list[dict[str, Any]]:
    """
    체결가에 슬리피지 반영 (매수 불리·매도 불리).

    Args:
        trades: amount_krw·price·action trade dict.
        slippage_pct: 체결가 대비 % (0.05 = 0.05%).

    Returns:
        price 조정된 trade dict 복사본.
    """
    slip = float(slippage_pct) / 100.0
    out: list[dict[str, Any]] = []
    for t in trades:
        row = dict(t)
        price = float(row.get("price") or 0)
        if price <= 0:
            out.append(row)
            continue
        action = row.get("action", "")
        if action == "buy":
            row["price"] = round(price * (1.0 + slip), 4)
        elif action == "sell":
            row["price"] = round(price * (1.0 - slip), 4)
        out.append(row)
    return out


def walk_forward_portfolio_by_month(
    steps: list[dict[str, Any]],
    *,
    initial_cash: float = GT_INITIAL_CASH_KRW,
) -> list[dict[str, Any]]:
    """
    포트폴리오 step에서 월별 자산 증감률 (인과적).

    Args:
        steps: simulate_portfolio_steps 결과.
        initial_cash: 첫 달 시작 자산(이전 달 종료 없을 때).

    Returns:
        {month, pnl_pct, start_asset, end_asset} 리스트.
    """
    if not steps:
        return []
    df = pd.DataFrame(steps)
    df["ts"] = pd.to_datetime(df["dt"])
    df = df.sort_values("ts")
    df["month"] = df["ts"].dt.to_period("M").astype(str)
    rows: list[dict[str, Any]] = []
    prev_end = float(initial_cash)
    for month in sorted(df["month"].unique()):
        grp = df[df["month"] == month]
        end_asset = float(grp["total_asset_krw"].iloc[-1])
        pnl_pct = (end_asset - prev_end) / prev_end * 100.0 if prev_end > 0 else 0.0
        rows.append(
            {
                "month": month,
                "pnl_pct": round(pnl_pct, 2),
                "start_asset_krw": round(prev_end, 0),
                "end_asset_krw": round(end_asset, 0),
            }
        )
        prev_end = end_asset
    return rows


def walk_forward_portfolio_summary(wf_rows: list[dict[str, Any]]) -> dict[str, Any]:
    """
    월별 포트폴리오 WF 요약.

    Args:
        wf_rows: walk_forward_portfolio_by_month 결과.

    Returns:
        months, positive_months, positive_ratio, mean_pnl_pct.
    """
    if not wf_rows:
        return {"months": 0, "positive_ratio": 0.0, "mean_pnl_pct": 0.0}
    n = len(wf_rows)
    pos = sum(1 for r in wf_rows if float(r.get("pnl_pct") or 0) > 0)
    mean_pnl = sum(float(r.get("pnl_pct") or 0) for r in wf_rows) / n
    return {
        "months": n,
        "positive_months": pos,
        "positive_ratio": round(pos / n, 4),
        "mean_pnl_pct": round(mean_pnl, 2),
    }


def simulate_hybrid_slippage_stress(
    sized_trades: list[dict[str, Any]],
    *,
    last_price: float | None,
    slippage_pct: float = LIVE_SLIPPAGE_PCT,
    initial_cash: float = GT_INITIAL_CASH_KRW,
    fee_rate: float,
) -> dict[str, Any]:
    """
    hybrid sized trades + 슬리피지 포트폴리오 요약.

    Args:
        sized_trades: build_monitor_hybrid_sized_trades 출력.
        last_price: 미청산 평가가.
        slippage_pct: 체결 슬리피지 %.
        initial_cash: 시작 현금.
        fee_rate: 수수료율.

    Returns:
        simulate_portfolio_summary 결과.
    """
    slipped = apply_slippage_to_trades(sized_trades, slippage_pct)
    result = simulate_portfolio_summary(
        slipped,
        initial_cash=initial_cash,
        fee_rate=fee_rate,
        last_price=last_price,
        use_amount_krw=True,
    )
    result["slippage_pct"] = slippage_pct
    result["sizing_mode"] = "hybrid_slippage_stress"
    return result


def evaluate_option_c_phase2_go(
    hybrid_go: dict[str, Any],
    hybrid_full: dict[str, Any],
    hybrid_holdout: dict[str, Any],
    hybrid_fee_stress: dict[str, Any],
    hybrid_slippage: dict[str, Any],
    portfolio_wf_summary: dict[str, Any],
    gt_pnl_pct: float,
) -> dict[str, Any]:
    """
    Option C 2차(+1000%) Go/No-Go.

    Args:
        hybrid_go: 1차 hybrid tier Go 결과.
        hybrid_full: 전기간 hybrid 포트폴리오.
        hybrid_holdout: holdout 구간 증감.
        hybrid_fee_stress: 수수료 2x hybrid.
        hybrid_slippage: 슬리피지 반영 hybrid.
        portfolio_wf_summary: 월별 포트폴리오 WF.
        gt_pnl_pct: GT 전기간 PnL %.

    Returns:
        go, checks, targets.
    """
    full_pnl = float(hybrid_full.get("pnl_pct", 0))
    capture = full_pnl / gt_pnl_pct if abs(gt_pnl_pct) > 1e-6 else 0.0
    ho_pnl = float(hybrid_holdout.get("pnl_pct", -999))
    mdd = float(hybrid_full.get("max_drawdown_pct", 999))
    fee_pnl = float(hybrid_fee_stress.get("pnl_pct", -999))
    slip_pnl = float(hybrid_slippage.get("pnl_pct", -999))
    wf_ratio = float(portfolio_wf_summary.get("positive_ratio", 0))

    c_phase1 = bool(hybrid_go.get("go"))
    c_pnl = full_pnl >= SIM_OPTION_C_PHASE2_TARGET_PNL_PCT
    c_capture = capture >= SIM_OPTION_C_MIN_GT_CAPTURE
    c_holdout = ho_pnl > 0.0
    c_mdd = mdd <= SIM_HYBRID_MAX_MDD_PCT
    c_fee = fee_pnl >= SIM_OPTION_C_PHASE2_TARGET_PNL_PCT * SIM_OPTION_C_PHASE2_FEE_STRESS_RATIO
    c_slip = slip_pnl > 0.0
    c_wf = wf_ratio >= SIM_HYBRID_PORTFOLIO_WF_MIN_RATIO

    all_go = (
        c_phase1
        and c_pnl
        and c_capture
        and c_holdout
        and c_mdd
        and c_fee
        and c_slip
        and c_wf
    )

    return {
        "go": all_go,
        "gt_capture_ratio": round(capture, 4),
        "targets": {
            "phase2_pnl_pct": SIM_OPTION_C_PHASE2_TARGET_PNL_PCT,
            "min_gt_capture": SIM_OPTION_C_MIN_GT_CAPTURE,
            "portfolio_wf_min_ratio": SIM_HYBRID_PORTFOLIO_WF_MIN_RATIO,
        },
        "checks": [
            {"name": "phase1_hybrid_go", "pass": c_phase1},
            {
                "name": "full_pnl_1000pct",
                "pass": c_pnl,
                "value": full_pnl,
            },
            {
                "name": "gt_capture_23pct",
                "pass": c_capture,
                "value": round(capture, 4),
            },
            {"name": "holdout_pnl_positive", "pass": c_holdout, "value": ho_pnl},
            {"name": "max_mdd", "pass": c_mdd, "value": mdd},
            {
                "name": "fee_stress_ratio",
                "pass": c_fee,
                "value": fee_pnl,
                "threshold": round(
                    SIM_OPTION_C_PHASE2_TARGET_PNL_PCT * SIM_OPTION_C_PHASE2_FEE_STRESS_RATIO,
                    2,
                ),
            },
            {
                "name": "slippage_stress_positive",
                "pass": c_slip,
                "value": slip_pnl,
                "note": "체결가 슬리피지 반영 후에도 흑자",
            },
            {
                "name": "portfolio_wf_positive_ratio",
                "pass": c_wf,
                "value": wf_ratio,
            },
        ],
    }
