"""Compliance domain entities with coverage calculation logic.

Pure domain logic — no framework imports.
"""

from __future__ import annotations

import enum
import uuid
from dataclasses import dataclass, field


class ControlCoverageStatus(str, enum.Enum):
    covered = "covered"
    partially_covered = "partially_covered"
    not_covered = "not_covered"


@dataclass
class ComplianceControlEntity:
    control_id: str
    title: str
    id: uuid.UUID | None = None
    description: str | None = None
    category: str | None = None
    technique_statuses: list[str] = field(default_factory=list)

    @property
    def coverage_status(self) -> ControlCoverageStatus:
        if not self.technique_statuses:
            return ControlCoverageStatus.not_covered
        covered_statuses = {"validated", "partial"}
        covered = [s for s in self.technique_statuses if s in covered_statuses]
        if len(covered) == len(self.technique_statuses):
            return ControlCoverageStatus.covered
        elif len(covered) > 0:
            return ControlCoverageStatus.partially_covered
        return ControlCoverageStatus.not_covered


@dataclass
class ComplianceFrameworkEntity:
    name: str
    id: uuid.UUID | None = None
    version: str | None = None
    description: str | None = None
    is_active: bool = True
    controls: list[ComplianceControlEntity] = field(default_factory=list)

    @property
    def total_controls(self) -> int:
        return len(self.controls)

    @property
    def covered_controls(self) -> int:
        return sum(
            1 for c in self.controls
            if c.coverage_status == ControlCoverageStatus.covered
        )

    @property
    def coverage_pct(self) -> float:
        if self.total_controls == 0:
            return 0.0
        return round(self.covered_controls / self.total_controls * 100, 1)

    def get_gap_controls(self) -> list[ComplianceControlEntity]:
        return [
            c for c in self.controls
            if c.coverage_status != ControlCoverageStatus.covered
        ]
