"""
并发模块类型定义
"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, List, Dict, Any, Callable, Awaitable, Generic, TypeVar
from enum import Enum


T = TypeVar('T')


# ==================== 负载测试类型 ====================

@dataclass
class LoadTestResult:
    """负载测试结果"""
    total_requests: int = 0
    successful_requests: int = 0
    failed_requests: int = 0
    total_duration_ms: float = 0
    avg_duration_ms: float = 0
    min_duration_ms: float = 0
    max_duration_ms: float = 0
    requests_per_second: float = 0
    errors: List[str] = field(default_factory=list)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "total_requests": self.total_requests,
            "successful_requests": self.successful_requests,
            "failed_requests": self.failed_requests,
            "total_duration_ms": round(self.total_duration_ms, 2),
            "avg_duration_ms": round(self.avg_duration_ms, 2),
            "min_duration_ms": round(self.min_duration_ms, 2),
            "max_duration_ms": round(self.max_duration_ms, 2),
            "requests_per_second": round(self.requests_per_second, 2),
            "error_rate": f"{self.failed_requests / self.total_requests * 100:.1f}%" if self.total_requests > 0 else "0%",
        }


# ==================== 浏览器池类型 ====================

@dataclass
class BrowserPoolConfig:
    """浏览器池配置"""
    max_instances: int = 5
    max_contexts_per_browser: int = 10
    browser_type: str = "chromium"
    headless: bool = True
    timeout: float = 30000
    idle_timeout: float = 300


@dataclass
class BrowserInstance:
    """浏览器实例"""
    id: str
    browser: Any  # Browser
    contexts: List[Any] = field(default_factory=list)
    created_at: datetime = field(default_factory=datetime.now)
    last_used: datetime = field(default_factory=datetime.now)
    is_busy: bool = False

    @property
    def context_count(self) -> int:
        return len(self.contexts)

    @property
    def idle_seconds(self) -> float:
        return (datetime.now() - self.last_used).total_seconds()


# ==================== 任务队列类型 ====================

class TaskStatus(Enum):
    """任务状态"""
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


@dataclass
class TaskQueueConfig:
    """任务队列配置"""
    max_concurrent: int = 5
    retry_count: int = 3
    retry_delay: float = 1.0
    timeout: float = 300
    auto_start: bool = True


@dataclass
class QueueTask(Generic[T]):
    """队列任务"""
    id: str
    name: str
    handler: Callable[..., Awaitable[T]]
    priority: int = 5
    args: tuple = field(default_factory=tuple)
    kwargs: Dict[str, Any] = field(default_factory=dict)
    status: TaskStatus = TaskStatus.PENDING
    result: Optional[T] = None
    error: Optional[str] = None
    created_at: datetime = field(default_factory=datetime.now)
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    retry_count: int = 0
    max_retries: int = 3
    dependencies: List[str] = field(default_factory=list)


# ==================== 重试执行器类型 ====================

@dataclass
class RetryConfig:
    """重试配置"""
    max_retries: int = 3
    base_delay: float = 1.0
    max_delay: float = 60.0
    exponential_base: float = 2.0
    jitter: bool = True
    jitter_range: float = 0.5
    timeout: Optional[float] = None
    retry_on: Optional[List[type]] = None
    retry_on_result: Optional[Callable[[Any], bool]] = None


@dataclass
class RetryResult(Generic[T]):
    """重试结果"""
    success: bool = False
    result: Optional[T] = None
    error: Optional[Exception] = None
    attempts: int = 0
    total_delay: float = 0.0
    errors: List[Exception] = field(default_factory=list)
    start_time: datetime = field(default_factory=datetime.now)
    end_time: Optional[datetime] = None

    @property
    def elapsed_seconds(self) -> float:
        if not self.end_time:
            return 0.0
        return (self.end_time - self.start_time).total_seconds()
