import time
from dataclasses import dataclass, field
from typing import Optional


@dataclass
class RequestMetrics:
    latency_ms: float = 0.0
    tls_handshake_ms: float = 0.0
    retry_count: int = 0
    redirect_depth: int = 0
    transport_used: str = "http1"
    status_code: Optional[int] = None
    challenge_solved: bool = False
    waf_vendor: Optional[str] = None


class MetricsCollector:
    def __init__(self):
        self._history: list[RequestMetrics] = []
        self._current: Optional[RequestMetrics] = None
        self._start_time: float = 0.0
        self._connect_time: float = 0.0

    def start(self, transport: str = "http1"):
        self._current = RequestMetrics(transport_used=transport)
        self._start_time = time.monotonic()
        self._connect_time = self._start_time

    def mark_connected(self):
        if self._current is not None:
            elapsed = (time.monotonic() - self._connect_time) * 1000
            self._current.tls_handshake_ms = round(elapsed, 2)

    def increment_retry(self):
        if self._current is not None:
            self._current.retry_count += 1

    def set_redirect_depth(self, depth: int):
        if self._current is not None:
            self._current.redirect_depth = depth

    def set_waf(self, vendor: str):
        if self._current is not None:
            self._current.waf_vendor = vendor

    def set_challenge_solved(self):
        if self._current is not None:
            self._current.challenge_solved = True

    def finish(self, response) -> RequestMetrics:
        if self._current is None:
            return RequestMetrics()
        elapsed = (time.monotonic() - self._start_time) * 1000
        self._current.latency_ms = round(elapsed, 2)
        if response is not None:
            self._current.status_code = response.status_code
            self._current.redirect_depth = len(getattr(response, 'history', []))
        self._history.append(self._current)
        m = self._current
        self._current = None
        return m

    def session_metrics(self) -> dict:
        if not self._history:
            return {}
        latencies = [m.latency_ms for m in self._history]
        return {
            "total_requests": len(self._history),
            "avg_latency_ms": round(sum(latencies) / len(latencies), 2),
            "max_latency_ms": max(latencies),
            "min_latency_ms": min(latencies),
            "total_retries": sum(m.retry_count for m in self._history),
            "challenges_solved": sum(1 for m in self._history if m.challenge_solved),
        }
