"""매매 기법 공통 인터페이스 및 결과 타입."""

from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import asdict, dataclass, field
from typing import Any

import pandas as pd


@dataclass
class TechniqueSignal:
    """기법이 생성한 매수·매도 신호."""

    side: str  # buy | sell
    bar_index: int
    price: float
    datetime: str
    pivot_bar_index: int | None = None
    confidence: float = 1.0
    reason: str = ""

    def to_dict(self) -> dict[str, Any]:
        """JSON 직렬화용 dict."""
        return asdict(self)


@dataclass
class TechniqueParams:
    """기법 실행 공통 파라미터."""

    interval_min: int
    lookback_days: int
    min_leg_pct: float
    initial_cash_krw: float
    fee_rate: float
    extra: dict[str, Any] = field(default_factory=dict)


@dataclass
class TechniqueResult:
    """기법 실행 결과 (GT JSON과 호환 구조)."""

    technique_id: str
    technique_name: str
    category: str
    causal: bool
    description: str
    params: dict[str, Any]
    signals: list[dict[str, Any]]
    legs: list[dict[str, Any]]
    summary: dict[str, Any]
    pnl: dict[str, Any]
    alignment: dict[str, Any] | None = None

    def to_dict(self) -> dict[str, Any]:
        """JSON 직렬화용 dict."""
        return asdict(self)


class BaseTechnique(ABC):
    """Ground Truth 정합을 목표로 하는 매매 기법 베이스."""

    technique_id: str
    technique_name: str
    category: str
    causal: bool
    description: str

    @abstractmethod
    def generate_signals(self, df: pd.DataFrame, params: TechniqueParams) -> list[TechniqueSignal]:
        """캔들 DataFrame에서 매수·매도 신호를 생성한다.

        Args:
            df: datetime, open, high, low, close, volume 컬럼.
            params: 공통 실행 파라미터.

        Returns:
            시간순 신호 리스트.
        """

    def default_extra_params(self) -> dict[str, Any]:
        """기법별 기본 추가 파라미터."""
        return {}
