from __future__ import annotations

from dataclasses import asdict, dataclass, field
from datetime import datetime
from typing import Any


CATEGORIES = (
    "SCAM",
    "DANGEROUS_ADVICE",
    "MISINFORMATION",
    "SPAM",
    "PROMOTION",
    "TOXIC",
    "PROFANITY",
)

CATEGORY_LABELS = {
    "SCAM": "Scam",
    "DANGEROUS_ADVICE": "Dangerous advice",
    "MISINFORMATION": "Misinformation",
    "SPAM": "Spam",
    "PROMOTION": "Promotion",
    "TOXIC": "Toxic",
    "PROFANITY": "Profanity",
    "SAFE": "Safe",
}

CATEGORY_COLORS = {
    "SCAM": "#DC2626",
    "DANGEROUS_ADVICE": "#DC2626",
    "MISINFORMATION": "#D97706",
    "SPAM": "#CA8A04",
    "PROMOTION": "#CA8A04",
    "TOXIC": "#9333EA",
    "PROFANITY": "#7E22CE",
    "SAFE": "#16A34A",
}

AVATAR_COLORS = (
    "#2563EB",
    "#7C3AED",
    "#DB2777",
    "#DC2626",
    "#EA580C",
    "#0F766E",
    "#15803D",
    "#334155",
)


@dataclass(slots=True)
class Profile:
    profile_id: str
    display_name: str
    report_email: str = ""
    avatar_color: str = AVATAR_COLORS[0]
    created_at: str = field(default_factory=lambda: datetime.now().isoformat(timespec="seconds"))
    updated_at: str = field(default_factory=lambda: datetime.now().isoformat(timespec="seconds"))

    scan_interval_seconds: int = 7
    risk_threshold: float = 0.72
    show_highlights: bool = True
    desktop_notifications: bool = True
    auto_save_reports: bool = True
    auto_email_high_risk: bool = False
    protect_while_hidden: bool = True
    repeat_cooldown_seconds: int = 120
    enabled_categories: list[str] = field(default_factory=lambda: list(CATEGORIES))

    smtp_server: str = "smtp.gmail.com"
    smtp_port: int = 587
    smtp_sender: str = ""

    def initials(self) -> str:
        pieces = [part for part in self.display_name.strip().split() if part]
        if not pieces:
            return "SJ"
        if len(pieces) == 1:
            return pieces[0][:2].upper()
        return (pieces[0][0] + pieces[-1][0]).upper()

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "Profile":
        valid = {field_name for field_name in cls.__dataclass_fields__}
        filtered = {key: value for key, value in data.items() if key in valid}
        profile = cls(**filtered)
        profile.scan_interval_seconds = max(3, min(120, int(profile.scan_interval_seconds)))
        profile.risk_threshold = max(0.5, min(0.99, float(profile.risk_threshold)))
        profile.repeat_cooldown_seconds = max(0, min(3600, int(profile.repeat_cooldown_seconds)))
        profile.enabled_categories = [c for c in profile.enabled_categories if c in CATEGORIES]
        if not profile.enabled_categories:
            profile.enabled_categories = list(CATEGORIES)
        if profile.avatar_color not in AVATAR_COLORS:
            profile.avatar_color = AVATAR_COLORS[0]
        return profile


@dataclass(slots=True)
class Detection:
    category: str
    risk: float
    text: str
    reason: str
    source: str = "manual"
    timestamp: str = field(default_factory=lambda: datetime.now().isoformat(timespec="seconds"))
    app_hint: str = ""
    x: int = 0
    y: int = 0
    width: int = 0
    height: int = 0
    detection_id: str = ""

    def __post_init__(self) -> None:
        self.risk = max(0.0, min(1.0, float(self.risk)))

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "Detection":
        valid = {field_name for field_name in cls.__dataclass_fields__}
        filtered = {key: value for key, value in data.items() if key in valid}
        return cls(**filtered)

    @property
    def location_text(self) -> str:
        if self.source != "screen":
            return self.source.replace("_", " ").title()
        return f"x={self.x}, y={self.y}, {self.width}×{self.height}"
