"""Strategies resource for Tradepose Client.

This module provides methods for managing trading strategies (register, list, get, delete).
"""

import logging

from tradepose_models.strategy import (
    ListStrategiesResponse,
    RegisterStrategyRequest,
    RegisterStrategyResponse,
)

from .base import BaseResource

logger = logging.getLogger(__name__)


class StrategiesResource(BaseResource):
    """Strategy management resource.

    This resource provides methods to manage trading strategies.
    All strategy operations are asynchronous and return task IDs for polling.

    Example:
        >>> async with TradeposeClient(api_key="tp_live_xxx") as client:
        ...     # Register a strategy
        ...     response = await client.strategies.register(
        ...         strategy_code=strategy_json,
        ...         overwrite=True
        ...     )
        ...     task_id = response.task_id
        ...
        ...     # Poll for completion
        ...     status = await client.tasks.get_status(task_id)
        ...     while status.status == "RUNNING":
        ...         await asyncio.sleep(2)
        ...         status = await client.tasks.get_status(task_id)
        ...
        ...     # List all strategies
        ...     list_response = await client.strategies.list(full=True)
        ...     list_task_id = list_response.task_id
    """

    async def register(
        self,
        strategy_code: str,
        overwrite: bool = False,
    ) -> RegisterStrategyResponse:
        """Register a new trading strategy.

        This is an asynchronous operation that returns a task_id.
        Poll /tasks/{task_id} to check completion status.

        The strategy_code should be a JSON string containing the complete
        StrategyConfig serialized with StrategyConfig.to_json().

        Args:
            strategy_code: Strategy configuration as JSON string
            overwrite: If True, overwrite existing strategy with same name

        Returns:
            RegisterStrategyResponse with task_id for polling

        Raises:
            AuthenticationError: If authentication fails
            ValidationError: If strategy_code is invalid
            TradeposeAPIError: For other API errors

        Example:
            >>> from tradepose_models.strategy import StrategyConfig
            >>>
            >>> # Create strategy config
            >>> strategy = StrategyConfig(
            ...     name="my_strategy",
            ...     base_instrument="BTCUSDT",
            ...     base_freq="1h",
            ...     # ... other config
            ... )
            >>>
            >>> # Register strategy
            >>> response = await client.strategies.register(
            ...     strategy_code=strategy.to_json(),
            ...     overwrite=True
            ... )
            >>> print(f"Task ID: {response.task_id}")
            >>>
            >>> # Poll for completion
            >>> status = await client.tasks.get_status(response.task_id)
            >>> while status.status in ["PENDING", "RUNNING"]:
            ...     await asyncio.sleep(2)
            ...     status = await client.tasks.get_status(response.task_id)
            >>>
            >>> if status.status == "COMPLETED":
            ...     print("Strategy registered successfully")
            >>> else:
            ...     print(f"Registration failed: {status.error}")
        """
        logger.info(f"Registering strategy (overwrite={overwrite})")

        request = RegisterStrategyRequest(
            strategy_code=strategy_code,
            overwrite=overwrite,
        )
        response_data = await self._post(
            "/api/v1/strategies",
            json=request,
        )

        result = RegisterStrategyResponse(**response_data)
        logger.info(f"Strategy registration task created: {result.task_id}")
        return result

    async def list(
        self,
        full: bool = False,
        instrument_id: str | None = None,
    ) -> ListStrategiesResponse:
        """List all strategies for the authenticated user.

        This is an asynchronous operation that returns a task_id.
        Poll /tasks/{task_id} to get the list of strategies.

        Args:
            full: If True, return full strategy configs; if False, return summary only
            instrument_id: Optional filter by instrument ID (e.g., "BTCUSDT")

        Returns:
            ListStrategiesResponse with task_id for polling

        Raises:
            AuthenticationError: If authentication fails
            TradeposeAPIError: For other API errors

        Example:
            >>> # List all strategies (summary)
            >>> response = await client.strategies.list()
            >>> task_id = response.task_id
            >>>
            >>> # Poll for results
            >>> status = await client.tasks.get_status(task_id)
            >>> while status.status in ["PENDING", "RUNNING"]:
            ...     await asyncio.sleep(1)
            ...     status = await client.tasks.get_status(task_id)
            >>>
            >>> if status.status == "COMPLETED":
            ...     # Download results
            ...     result = await client.tasks.download_result_by_type(
            ...         task_id,
            ...         result_type="strategies"
            ...     )
            ...     print(f"Strategies: {result}")
            >>>
            >>> # List strategies for specific instrument
            >>> response = await client.strategies.list(
            ...     full=True,
            ...     instrument_id="BTCUSDT"
            ... )
        """
        logger.debug(f"Listing strategies (full={full}, instrument_id={instrument_id})")

        params = {"full": str(full).lower()}
        if instrument_id:
            params["instrument_id"] = instrument_id

        response_data = await self._get(
            "/api/v1/strategies",
            params=params,
        )

        result = ListStrategiesResponse(**response_data)
        logger.info(f"Strategy list task created: {result.task_id}")
        return result

    async def get(self, strategy_name: str) -> RegisterStrategyResponse:
        """Get a specific strategy by name.

        This is an asynchronous operation that returns a task_id.
        Poll /tasks/{task_id} to get the strategy details.

        Args:
            strategy_name: Name of the strategy to retrieve

        Returns:
            RegisterStrategyResponse with task_id for polling

        Raises:
            ResourceNotFoundError: If strategy not found
            AuthenticationError: If authentication fails
            TradeposeAPIError: For other API errors

        Example:
            >>> # Get strategy
            >>> response = await client.strategies.get("my_strategy")
            >>> task_id = response.task_id
            >>>
            >>> # Poll for results
            >>> status = await client.tasks.get_status(task_id)
            >>> while status.status in ["PENDING", "RUNNING"]:
            ...     await asyncio.sleep(1)
            ...     status = await client.tasks.get_status(task_id)
            >>>
            >>> if status.status == "COMPLETED":
            ...     # Download strategy config
            ...     result = await client.tasks.download_result_by_type(
            ...         task_id,
            ...         result_type="strategy"
            ...     )
            ...     # Parse into StrategyConfig
            ...     from tradepose_models.strategy import StrategyConfig
            ...     strategy = StrategyConfig.model_validate(result)
            ...     print(f"Strategy: {strategy.name}")
        """
        logger.info(f"Getting strategy: {strategy_name}")

        response_data = await self._get(f"/api/v1/strategies/{strategy_name}")

        result = RegisterStrategyResponse(**response_data)
        logger.info(f"Strategy get task created: {result.task_id}")
        return result

    async def delete(self, strategy_name: str) -> RegisterStrategyResponse:
        """Delete a strategy by name.

        This is an asynchronous operation that returns a task_id.
        Poll /tasks/{task_id} to check deletion status.

        Args:
            strategy_name: Name of the strategy to delete

        Returns:
            RegisterStrategyResponse with task_id for polling

        Raises:
            ResourceNotFoundError: If strategy not found
            AuthenticationError: If authentication fails
            TradeposeAPIError: For other API errors

        Example:
            >>> # Delete strategy
            >>> response = await client.strategies.delete("my_strategy")
            >>> task_id = response.task_id
            >>>
            >>> # Poll for completion
            >>> status = await client.tasks.get_status(task_id)
            >>> while status.status in ["PENDING", "RUNNING"]:
            ...     await asyncio.sleep(1)
            ...     status = await client.tasks.get_status(task_id)
            >>>
            >>> if status.status == "COMPLETED":
            ...     print("Strategy deleted successfully")
            >>> else:
            ...     print(f"Deletion failed: {status.error}")
        """
        logger.info(f"Deleting strategy: {strategy_name}")

        response_data = await self._delete(f"/api/v1/strategies/{strategy_name}")

        result = RegisterStrategyResponse(**response_data)
        logger.info(f"Strategy delete task created: {result.task_id}")
        return result
