"""Models for the sharing module."""

from __future__ import annotations

from enum import Enum
from pathlib import Path
from typing import Any

from pydantic import BaseModel, Field


class ContentType(str, Enum):
    """Type of shareable content."""

    PROFILE = "profile"
    SPEC = "spec"


class TrustLevel(str, Enum):
    """Trust level of imported content."""

    LOCAL = "local"  # User-created locally
    REMOTE = "remote"  # Fetched from URL


class Severity(str, Enum):
    """Severity level for security findings."""

    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"


class SecurityFinding(BaseModel):
    """A security scan finding."""

    severity: Severity = Field(..., description="Severity level")
    category: str = Field(..., description="Finding category")
    message: str = Field(..., description="Human-readable message")
    location: str | None = Field(default=None, description="Location in content")

    def __str__(self) -> str:
        loc = f" at {self.location}" if self.location else ""
        return f"[{self.severity.value.upper()}] {self.category}: {self.message}{loc}"


class SecurityScanResult(BaseModel):
    """Result of a security scan."""

    passed: bool = Field(..., description="Whether scan passed (no critical issues)")
    risk_level: str = Field(..., description="Overall risk level: low, medium, high, critical")
    findings: list[SecurityFinding] = Field(
        default_factory=list, description="List of findings"
    )

    @property
    def critical_count(self) -> int:
        """Count of critical findings."""
        return sum(1 for f in self.findings if f.severity == Severity.CRITICAL)

    @property
    def warning_count(self) -> int:
        """Count of warning findings."""
        return sum(1 for f in self.findings if f.severity == Severity.WARNING)

    @property
    def has_critical(self) -> bool:
        """Check if there are any critical findings."""
        return self.critical_count > 0

    def get_by_severity(self, severity: Severity) -> list[SecurityFinding]:
        """Get findings by severity."""
        return [f for f in self.findings if f.severity == severity]

    @classmethod
    def empty(cls) -> SecurityScanResult:
        """Create an empty (passed) scan result."""
        return cls(passed=True, risk_level="low", findings=[])


class ImportResult(BaseModel):
    """Result of an import operation."""

    success: bool = Field(..., description="Whether import succeeded")
    content_type: ContentType = Field(..., description="Type of imported content")
    name: str = Field(..., description="Name of imported content")
    source_url: str = Field(..., description="Source URL")
    local_path: Path | None = Field(default=None, description="Path where saved locally")
    trust_level: TrustLevel = Field(default=TrustLevel.REMOTE, description="Trust level")
    security_scan: SecurityScanResult | None = Field(
        default=None, description="Security scan result"
    )
    warnings: list[str] = Field(default_factory=list, description="Warning messages")
    errors: list[str] = Field(default_factory=list, description="Error messages")

    @property
    def has_warnings(self) -> bool:
        """Check if there are any warnings."""
        return len(self.warnings) > 0 or (
            self.security_scan is not None and self.security_scan.warning_count > 0
        )


class ImportedContentMetadata(BaseModel):
    """Metadata stored alongside imported content."""

    source_url: str = Field(..., description="Original source URL")
    imported_at: str = Field(..., description="ISO timestamp of import")
    trust_level: TrustLevel = Field(default=TrustLevel.REMOTE)
    content_type: ContentType = Field(...)
    security_scan_passed: bool = Field(default=True)
    original_name: str | None = Field(default=None, description="Original name from content")
