from collections.abc import Mapping
from dataclasses import dataclass
from datetime import datetime
from typing import Any

from .base import parse_datetime


@dataclass(frozen=True, slots=True)
class ReportInfo:
    reported_at: datetime
    comment: str
    categories: tuple[int, ...]
    reporter_id: int
    reporter_country_code: str | None
    reporter_country_name: str | None

    @classmethod
    def from_dict(cls, value: Mapping[str, Any]) -> "ReportInfo":
        return cls(
            reported_at=parse_datetime(value["reportedAt"]),
            comment=value["comment"],
            categories=tuple(value["categories"]),
            reporter_id=value["reporterId"],
            reporter_country_code=value.get("reporterCountryCode"),
            reporter_country_name=value.get("reporterCountryName"),
        )


@dataclass(frozen=True, slots=True)
class BlacklistedIP:
    ip_address: str
    country_code: str | None
    abuse_confidence_score: int
    last_reported_at: datetime

    @classmethod
    def from_dict(cls, value: Mapping[str, Any]) -> "BlacklistedIP":
        return cls(
            ip_address=value["ipAddress"],
            country_code=value.get("countryCode"),
            abuse_confidence_score=value["abuseConfidenceScore"],
            last_reported_at=parse_datetime(value["lastReportedAt"]),
        )


@dataclass(frozen=True, slots=True)
class BulkInvalidReport:
    error: str
    input: str
    row_number: int

    @classmethod
    def from_dict(cls, value: Mapping[str, Any]) -> "BulkInvalidReport":
        return cls(error=value["error"], input=value["input"], row_number=value["rowNumber"])


@dataclass(frozen=True, slots=True)
class CheckBlockIP:
    ip_address: str
    num_reports: int
    most_recent_report: datetime
    country_code: str | None
    abuse_confidence_score: int

    @classmethod
    def from_dict(cls, value: Mapping[str, Any]) -> "CheckBlockIP":
        return cls(
            ip_address=value["ipAddress"],
            num_reports=value["numReports"],
            most_recent_report=parse_datetime(value["mostRecentReport"]),
            country_code=value.get("countryCode"),
            abuse_confidence_score=value["abuseConfidenceScore"],
        )
