"""Threat actor domain entity with coverage analysis logic.

Pure domain logic — no framework imports.
"""

from __future__ import annotations

import uuid
from dataclasses import dataclass, field
from typing import Any


@dataclass
class ThreatActorTechniqueRef:
    """Lightweight reference to a technique used by an actor."""

    technique_id: uuid.UUID
    mitre_id: str | None = None
    name: str | None = None
    status: str | None = None
    usage_description: str | None = None


@dataclass
class ThreatActorEntity:
    name: str
    id: uuid.UUID | None = None
    mitre_id: str | None = None
    aliases: list[str] = field(default_factory=list)
    description: str | None = None
    country: str | None = None
    target_sectors: list[str] = field(default_factory=list)
    target_regions: list[str] = field(default_factory=list)
    motivation: str | None = None
    sophistication: str | None = None
    first_seen: str | None = None
    last_seen: str | None = None
    is_active: bool = True
    techniques: list[ThreatActorTechniqueRef] = field(default_factory=list)

    @property
    def technique_count(self) -> int:
        return len(self.techniques)

    @property
    def covered_techniques(self) -> list[ThreatActorTechniqueRef]:
        return [
            t for t in self.techniques
            if t.status in ("validated", "partial")
        ]

    @property
    def uncovered_techniques(self) -> list[ThreatActorTechniqueRef]:
        return [
            t for t in self.techniques
            if t.status not in ("validated", "partial")
        ]

    @property
    def coverage_pct(self) -> float:
        if not self.techniques:
            return 0.0
        return round(len(self.covered_techniques) / len(self.techniques) * 100, 1)

    @classmethod
    def from_orm(cls, orm: Any) -> ThreatActorEntity:
        techs: list[ThreatActorTechniqueRef] = []
        for tat in getattr(orm, "techniques", None) or []:
            technique = getattr(tat, "technique", None)
            techs.append(ThreatActorTechniqueRef(
                technique_id=tat.technique_id,
                mitre_id=getattr(technique, "mitre_id", None) if technique else None,
                name=getattr(technique, "name", None) if technique else None,
                status=(
                    technique.status_global.value
                    if technique and hasattr(technique.status_global, "value")
                    else getattr(technique, "status_global", None) if technique else None
                ),
                usage_description=tat.usage_description,
            ))
        return cls(
            id=orm.id,
            name=orm.name,
            mitre_id=orm.mitre_id,
            aliases=orm.aliases or [],
            description=orm.description,
            country=orm.country,
            target_sectors=orm.target_sectors or [],
            target_regions=orm.target_regions or [],
            motivation=orm.motivation,
            sophistication=orm.sophistication,
            first_seen=orm.first_seen,
            last_seen=orm.last_seen,
            is_active=orm.is_active if orm.is_active is not None else True,
            techniques=techs,
        )
