import asyncio
import logging
from typing import Tuple
from danding_bot.plugins.danding_points import points_api
from .config import Config

logger = logging.getLogger("horse_racing.points")

MAX_RETRIES = 3
RETRY_DELAY = 0.5


class PointsService:
    def __init__(self, config: Config):
        self.config = config

    async def _call_with_retry(self, func, *args, retries=MAX_RETRIES):
        """Call API function with retry logic."""
        last_exc = None
        for attempt in range(retries):
            try:
                return await func(*args)
            except Exception as e:
                last_exc = e
                logger.warning(
                    f"Points API call failed (attempt {attempt + 1}/{retries}): {e}"
                )
                if attempt < retries - 1:
                    await asyncio.sleep(RETRY_DELAY)
        logger.error(f"Points API call failed after {retries} attempts: {last_exc}")
        raise last_exc

    async def spend_bet_points(
        self, user_id: str, amount: int, reason: str = "赛马下注"
    ) -> Tuple[bool, int]:
        """Deduct points for betting with retry."""
        try:
            return await self._call_with_retry(
                points_api.spend_points,
                user_id, amount, "horse_race", reason
            )
        except Exception as e:
            logger.error(f"spend_bet_points failed for user {user_id}: {e}")
            return False, 0

    async def refund_bet_points(
        self, user_id: str, amount: int, reason: str = "取消报名退还"
    ) -> Tuple[bool, int]:
        """Refund bet points."""
        return await points_api.add_points(user_id, amount, "horse_race", reason)

    async def payout_winnings(
        self, user_id: str, amount: int, odds: float
    ) -> Tuple[bool, int]:
        """Payout bet winnings."""
        payout = max(1, round(amount * odds))
        reason = f"下注获胜 ×{odds:.2f}"
        return await points_api.add_points(user_id, payout, "horse_race", reason)

    async def reward_participant(self, user_id: str) -> Tuple[bool, int]:
        """Reward race participant."""
        return await points_api.add_points(
            user_id,
            self.config.PARTICIPANT_REWARD,
            "horse_race",
            "参赛奖励",
        )

    async def reward_champion(self, user_id: str) -> Tuple[bool, int]:
        """Reward race champion."""
        return await points_api.add_points(
            user_id,
            self.config.CHAMPION_REWARD,
            "horse_race",
            "冠军奖励",
        )

    async def set_points(
        self, user_id: str, amount: int, reason: str = "测试设置积分"
    ) -> Tuple[bool, int]:
        """Set user points (for testing)."""
        return await points_api.set_points(user_id, amount, "horse_race", reason)

    async def get_balance(self, user_id: str) -> int:
        """Get user balance."""
        return await points_api.get_balance(user_id)
