"""策略管理 API"""

import json
from typing import Dict, List, Union
import requests


class StrategyAPI:
    """策略管理 API Mixin"""

    def list_strategies(
        self, full: bool = False, instrument_id: Union[str, None] = None
    ) -> List[Dict]:
        """列出所有可用策略

        Args:
            full: True 返回完整配置，False 返回简化列表（默认）
            instrument_id: 按商品 ID 过滤（可选）

        Returns:
            策略列表（简化或完整格式）

        Example:
            >>> # 获取简化列表
            >>> strategies = client.list_strategies()
            >>>
            >>> # 获取完整配置
            >>> full_configs = client.list_strategies(full=True)
            >>>
            >>> # 按商品过滤
            >>> txf_strategies = client.list_strategies(instrument_id="TXF_M1_SHIOAJI_FUTURE")
            >>>
            >>> # 组合使用
            >>> txf_full = client.list_strategies(
            ...     full=True,
            ...     instrument_id="TXF_M1_SHIOAJI_FUTURE"
            ... )
        """
        params = {}
        if full:
            params["full"] = "true"
        if instrument_id:
            params["instrument_id"] = instrument_id

        response = requests.get(
            f"{self.api_url}/api/v1/strategies",
            params=params,
            headers=self._get_headers(),
        )
        response.raise_for_status()
        return response.json()

    def get_strategy_detail(self, strategy_name: str) -> Dict:
        """獲取策略詳情

        Args:
            strategy_name: 策略名稱

        Returns:
            策略詳情
        """
        response = requests.get(
            f"{self.api_url}/api/v1/strategies/{strategy_name}",
            headers=self._get_headers(),
        )
        response.raise_for_status()
        return response.json()

    def register_strategy(self, strategy_config, overwrite: bool = False) -> Dict:
        """註冊策略（支持單個或批量註冊）

        Args:
            strategy_config: StrategyConfig 實例或 List[StrategyConfig]
            overwrite: 是否覆蓋已存在的策略（默認 False）

        Returns:
            註冊結果（包含 succeeded/failed 或批量結果信息）

        Raises:
            requests.HTTPError: 400 (Invalid request), 409 (Already exists), 500

        Example:
            >>> from tradepose_client.models import StrategyConfig
            >>>
            >>> # 單個註冊
            >>> strategy = StrategyConfig(...)
            >>> response = client.register_strategy(strategy)
            >>>
            >>> # 覆蓋註冊
            >>> response = client.register_strategy(strategy, overwrite=True)
            >>>
            >>> # 批量註冊
            >>> strategies = [StrategyConfig(...), StrategyConfig(...)]
            >>> response = client.register_strategy(strategies)
            >>>
            >>> # 批量覆蓋
            >>> response = client.register_strategy(strategies, overwrite=True)
        """
        from ..models import StrategyConfig

        # 判斷是否為列表（批量）
        if isinstance(strategy_config, list):
            # 批量註冊：直接傳遞配置列表
            configs = []
            for cfg in strategy_config:
                if isinstance(cfg, StrategyConfig):
                    configs.append(cfg.to_dict())
                else:
                    configs.append(cfg)
            payload = configs
        else:
            # 單個註冊：直接傳遞 strategy_config 對象（不需要 {"config": ...} 包裝）
            assert isinstance(
                strategy_config, StrategyConfig
            ), "strategy_config 必須是 StrategyConfig 實例或其列表"
            payload = strategy_config.to_dict()

        # 構建 URL（帶 overwrite 參數）
        url = f"{self.api_url}/api/v1/strategies"
        if overwrite:
            url += "?overwrite=true"

        response = requests.post(
            url,
            json=payload,
            headers=self._get_headers(),
        )
        response.raise_for_status()
        return response.json()


    def delete_strategy(self, strategy_name: Union[str, List[str]]) -> Dict:
        """刪除策略（支持單個或批量刪除）

        內部使用 POST /api/v1/strategies/delete 端點

        Args:
            strategy_name: 策略名稱（str）或策略名稱列表（List[str]）

        Returns:
            刪除結果（包含 deleted/not_found 信息）

        Example:
            >>> # 單個刪除
            >>> client.delete_strategy("my_strategy")
            >>>
            >>> # 批量刪除
            >>> client.delete_strategy(["strategy1", "strategy2", "strategy3"])
        """
        # 判斷是否為列表
        if isinstance(strategy_name, list):
            names = strategy_name
        else:
            names = [strategy_name]

        response = requests.post(
            f"{self.api_url}/api/v1/strategies/delete",
            json=names,
            headers=self._get_headers(),
        )
        response.raise_for_status()
        return response.json()

    def clear_strategies(self) -> Dict:
        """清空所有策略（使用批量刪除端點）

        Returns:
            刪除結果（包含 deleted/not_found 信息）
        """
        strategies = self.list_strategies()
        if not strategies:
            return {
                "deleted": [],
                "not_found": [],
                "total": 0,
                "deleted_count": 0,
                "not_found_count": 0,
            }

        strategy_names = [s["name"] for s in strategies]
        return self.delete_strategy(strategy_names)

    def add_blueprint(self, strategy_name: str, blueprint) -> Dict:
        """為策略添加進階 Blueprint

        Args:
            strategy_name: 策略名稱
            blueprint: Blueprint 實例

        Returns:
            添加結果

        Raises:
            requests.HTTPError: 404 (Strategy not found), 500

        Example:
            >>> from tradepose_client.models import create_blueprint, create_trigger
            >>> import polars as pl
            >>>
            >>> # 創建 blueprint
            >>> entry = create_trigger(
            ...     name="reversal_entry",
            ...     conditions=[pl.col("rsi") < 30],
            ...     price_expr=pl.col("open")
            ... )
            >>> blueprint = create_blueprint(
            ...     name="reversal_strategy",
            ...     direction="Long",
            ...     entry_triggers=[entry],
            ...     exit_triggers=[]
            ... )
            >>>
            >>> # 添加到策略
            >>> client.add_blueprint("my_strategy", blueprint)
        """
        from ..models import Blueprint

        assert isinstance(blueprint, Blueprint), "blueprint 必須是 Blueprint 實例"

        payload = {"blueprint": blueprint.model_dump()}

        response = requests.post(
            f"{self.api_url}/api/v1/strategies/{strategy_name}/blueprints",
            json=payload,
            headers=self._get_headers(),
        )
        response.raise_for_status()
        return response.json()
