"""AuctionHouse - 拍卖机制，基于竞价选择 Agent"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any

from agentkit.marketplace.wealth import WealthTracker


@dataclass
class Bid:
    """Agent 竞价信息"""

    agent_name: str
    architecture: str  # "react", "rewoo", "plan_exec", "reflexion", "direct"
    estimated_steps: int
    estimated_cost: float  # estimated token cost
    confidence: float  # 0.0-1.0 confidence in completing the task
    payment_offer: float  # how much the agent "charges"
    capabilities: list[str] = field(default_factory=list)
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class AuctionResult:
    """拍卖结果"""

    winner: Bid | None
    all_bids: list[Bid]
    selection_reason: str
    total_bidders: int


class AuctionHouse:
    """Auction-based agent selection mechanism.

    Default disabled. Enable via marketplace.auction_enabled: true in config.
    When enabled, Layer 2 routing uses auction instead of capability matching.
    """

    def __init__(self, wealth_tracker: WealthTracker | None = None) -> None:
        self._wealth_tracker = wealth_tracker or WealthTracker()

    async def run_auction(self, task_description: str, bidders: list[Bid]) -> AuctionResult:
        """Run auction among bidders, select winner.

        Scoring formula:
        score = (confidence / max(estimated_cost, 0.001)) * wealth_factor

        wealth_factor = 1.0 + (wealth / 1000.0)  # wealth bonus, diminishing returns
        """
        if not bidders:
            return AuctionResult(
                winner=None,
                all_bids=[],
                selection_reason="No bidders participated",
                total_bidders=0,
            )

        # Filter out bankrupt agents
        eligible = [
            b for b in bidders
            if not self._wealth_tracker.is_bankrupt(b.agent_name)
        ]

        if not eligible:
            return AuctionResult(
                winner=None,
                all_bids=bidders,
                selection_reason="All bidders are bankrupt",
                total_bidders=len(bidders),
            )

        # Score each bid
        scored: list[tuple[Bid, float]] = []
        for bid in eligible:
            score = self.score_bid(bid)
            scored.append((bid, score))

        # Select highest score
        scored.sort(key=lambda x: x[1], reverse=True)
        winner, winner_score = scored[0]

        return AuctionResult(
            winner=winner,
            all_bids=bidders,
            selection_reason=(
                f"Agent '{winner.agent_name}' won with score {winner_score:.4f} "
                f"(confidence={winner.confidence}, cost={winner.estimated_cost}, "
                f"wealth_factor={self._wealth_tracker.get_wealth_factor(winner.agent_name):.4f})"
            ),
            total_bidders=len(bidders),
        )

    def score_bid(self, bid: Bid) -> float:
        """Calculate bid score without running full auction"""
        wealth_factor = self._wealth_tracker.get_wealth_factor(bid.agent_name)
        score = (bid.confidence / max(bid.estimated_cost, 0.001)) * wealth_factor
        return score
