"""Runs resource for TradePose Client.

Provides by-reference backtest submission via blueprint_ids or portfolio_id.
"""

import logging
from uuid import UUID

from tradepose_models.enums import PersistMode
from tradepose_models.enums.export_type import ExportType
from tradepose_models.export import ExportResponse, RunRequest

from .base import BaseResource

logger = logging.getLogger(__name__)


class RunsResource(BaseResource):
    """Submit backtest tasks by referencing DB resources.

    Users with persisted strategies can submit backtest tasks without
    reconstructing StrategyConfig objects — simply pass blueprint_ids
    or a portfolio_id.

    Example:
        >>> async with TradePoseClient(api_key="tp_live_xxx") as client:
        ...     # Via blueprint_ids
        ...     response = await client.runs.create(
        ...         blueprint_ids=[bp1_id, bp2_id],
        ...         start_date="2025-01-01",
        ...         end_date="2025-12-31",
        ...     )
        ...
        ...     # Via portfolio_id
        ...     portfolios = await client.portfolios.list()
        ...     response = await client.runs.create(
        ...         portfolio_id=portfolios.portfolios[0].id,
        ...         start_date="2025-01-01",
        ...         end_date="2025-12-31",
        ...     )
        ...
        ...     # Poll and download (same as export)
        ...     trades_df, perf_df = await client.tasks.download_backtest_results(response.task_id)
    """

    async def create(
        self,
        *,
        blueprint_ids: list[UUID] | None = None,
        portfolio_id: UUID | None = None,
        export_type: ExportType = ExportType.BACKTEST_RESULTS,
        persist_mode: PersistMode = PersistMode.PSQL,
        start_date: str | None = None,
        end_date: str | None = None,
        trade_count: int | None = None,
    ) -> ExportResponse:
        """Submit a backtest run by referencing DB resources.

        Exactly one of blueprint_ids or portfolio_id must be provided.

        Args:
            blueprint_ids: List of blueprint UUIDs to run.
            portfolio_id: Portfolio UUID whose allocations define the blueprints.
            export_type: Type of export (default: BACKTEST_RESULTS).
            persist_mode: Where to persist results (default: PSQL).
            start_date: Backtest start date ISO 8601 (required for BACKTEST_RESULTS / ENHANCED_OHLCV).
            end_date: Backtest end date ISO 8601 (required for BACKTEST_RESULTS / ENHANCED_OHLCV).
            trade_count: Number of latest trades per blueprint (LATEST_TRADES only).

        Returns:
            ExportResponse with task_id for polling via client.tasks.

        Raises:
            ValidationError: If both or neither of blueprint_ids/portfolio_id are provided.
            ResourceNotFoundError: If any blueprint or portfolio is not found.
            AuthenticationError: If authentication fails.
            TradePoseAPIError: For other API errors.
        """
        request = RunRequest(
            blueprint_ids=blueprint_ids,
            portfolio_id=portfolio_id,
            export_type=export_type,
            persist_mode=persist_mode,
            start_date=start_date,
            end_date=end_date,
            trade_count=trade_count,
        )

        logger.debug(
            f"Creating run task: export_type={export_type}, "
            f"blueprint_ids={blueprint_ids}, portfolio_id={portfolio_id}"
        )

        response_data = await self._post("/api/v1/runs", json=request)
        result = ExportResponse(**response_data)
        logger.debug(f"Run task created: {result.task_id} ({result.operation_type})")
        return result
