"""이동평균 골든·데드 크로스."""

from __future__ import annotations

import pandas as pd

from deepcoin.techniques.base import BaseTechnique, TechniqueParams, TechniqueSignal
from deepcoin.techniques.indicators import ema


class MaCrossTechnique(BaseTechnique):
    """단기 EMA가 장기 EMA를 상향 돌파 시 매수, 하향 돌파 시 매도."""

    technique_id = "ma_cross"
    technique_name = "EMA 크로스"
    category = "indicator"
    causal = True
    description = "EMA(20/60) 골든크로스 매수·데드크로스 매도"

    def default_extra_params(self) -> dict:
        return {"fast_span": 20, "slow_span": 60}

    def generate_signals(self, df: pd.DataFrame, params: TechniqueParams) -> list[TechniqueSignal]:
        fast_span = int(params.extra.get("fast_span", 20))
        slow_span = int(params.extra.get("slow_span", 60))

        close = df["close"].astype(float)
        fast = ema(close, fast_span)
        slow = ema(close, slow_span)

        signals: list[TechniqueSignal] = []
        start = max(fast_span, slow_span)

        for i in range(start + 1, len(df)):
            if pd.isna(fast.iloc[i]) or pd.isna(slow.iloc[i]):
                continue

            prev_fast = float(fast.iloc[i - 1])
            prev_slow = float(slow.iloc[i - 1])
            curr_fast = float(fast.iloc[i])
            curr_slow = float(slow.iloc[i])
            price = float(close.iloc[i])
            dt = pd.Timestamp(df.iloc[i]["datetime"]).strftime("%Y-%m-%d %H:%M:%S")

            if prev_fast <= prev_slow and curr_fast > curr_slow:
                signals.append(
                    TechniqueSignal(
                        side="buy",
                        bar_index=i,
                        price=round(price, 2),
                        datetime=dt,
                        confidence=0.6,
                        reason="golden_cross",
                    )
                )
            elif prev_fast >= prev_slow and curr_fast < curr_slow:
                signals.append(
                    TechniqueSignal(
                        side="sell",
                        bar_index=i,
                        price=round(price, 2),
                        datetime=dt,
                        confidence=0.6,
                        reason="death_cross",
                    )
                )

        return signals
