"""
Service Module Registry models — extracted from compliance/db/models.py.

Sprint 3: registry of all Breakpilot services/modules for compliance mapping,
per-module regulation applicability, and per-module risk aggregation.
Re-exported from ``compliance.db.models`` for backwards compatibility.

DO NOT change __tablename__, column names, or relationship strings.
"""

import uuid
import enum
from datetime import datetime, timezone

from sqlalchemy import (
    Column, String, Text, Integer, Boolean, DateTime,
    ForeignKey, Enum, JSON, Index, Float,
)
from sqlalchemy.orm import relationship

from classroom_engine.database import Base
# RiskLevelEnum is re-used across aggregates; sourced here from control_models.
from compliance.db.control_models import RiskLevelEnum  # noqa: F401


# ============================================================================
# ENUMS
# ============================================================================

class ServiceTypeEnum(str, enum.Enum):
    """Type of Breakpilot service/module."""
    BACKEND = "backend"           # API/Backend services
    DATABASE = "database"         # Data storage
    AI = "ai"                     # AI/ML services
    COMMUNICATION = "communication"  # Chat/Video/Messaging
    STORAGE = "storage"           # File/Object storage
    INFRASTRUCTURE = "infrastructure"  # Load balancer, reverse proxy
    MONITORING = "monitoring"     # Logging, metrics
    SECURITY = "security"         # Auth, encryption, secrets


class RelevanceLevelEnum(str, enum.Enum):
    """Relevance level of a regulation to a service."""
    CRITICAL = "critical"         # Non-compliance = shutdown
    HIGH = "high"                 # Major risk
    MEDIUM = "medium"             # Moderate risk
    LOW = "low"                   # Minor risk


# ============================================================================
# MODELS
# ============================================================================

class ServiceModuleDB(Base):
    """
    Registry of all Breakpilot services/modules for compliance mapping.

    Tracks which regulations apply to which services, enabling:
    - Service-specific compliance views
    - Aggregated risk per service
    - Gap analysis by module
    """
    __tablename__ = 'compliance_service_modules'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String(100), unique=True, nullable=False, index=True)  # e.g., "consent-service"
    display_name = Column(String(200), nullable=False)                     # e.g., "Go Consent Service"
    description = Column(Text)

    # Technical details
    service_type = Column(Enum(ServiceTypeEnum), nullable=False)
    port = Column(Integer)                                                 # Primary port (if applicable)
    technology_stack = Column(JSON)                                        # e.g., ["Go", "Gin", "PostgreSQL"]
    repository_path = Column(String(500))                                  # e.g., "/consent-service"
    docker_image = Column(String(200))                                     # e.g., "breakpilot-pwa-consent-service"

    # Data categories handled
    data_categories = Column(JSON)                                         # e.g., ["personal_data", "consent_records"]
    processes_pii = Column(Boolean, default=False)                         # Handles personally identifiable info?
    processes_health_data = Column(Boolean, default=False)                 # Handles special category health data?
    ai_components = Column(Boolean, default=False)                         # Contains AI/ML components?

    # Status
    is_active = Column(Boolean, default=True)
    criticality = Column(String(20), default="medium")                     # "critical", "high", "medium", "low"

    # Compliance aggregation
    compliance_score = Column(Float)                                       # Calculated score 0-100
    last_compliance_check = Column(DateTime)

    # Owner
    owner_team = Column(String(100))                                       # e.g., "Backend Team"
    owner_contact = Column(String(200))                                    # e.g., "backend@breakpilot.app"

    # Timestamps
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))

    # Relationships
    regulation_mappings = relationship("ModuleRegulationMappingDB", back_populates="module", cascade="all, delete-orphan")
    module_risks = relationship("ModuleRiskDB", back_populates="module", cascade="all, delete-orphan")

    __table_args__ = (
        Index('ix_module_type_active', 'service_type', 'is_active'),
    )

    def __repr__(self):
        return f"<ServiceModule {self.name}: {self.display_name}>"


class ModuleRegulationMappingDB(Base):
    """
    Maps services to applicable regulations with relevance level.

    Enables filtering: "Show all GDPR requirements for consent-service"
    """
    __tablename__ = 'compliance_module_regulations'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    module_id = Column(String(36), ForeignKey('compliance_service_modules.id'), nullable=False, index=True)
    regulation_id = Column(String(36), ForeignKey('compliance_regulations.id'), nullable=False, index=True)

    relevance_level = Column(Enum(RelevanceLevelEnum), nullable=False, default=RelevanceLevelEnum.MEDIUM)
    notes = Column(Text)                                                   # Why this regulation applies
    applicable_articles = Column(JSON)                                     # List of specific articles that apply

    # Timestamps
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))

    # Relationships
    module = relationship("ServiceModuleDB", back_populates="regulation_mappings")
    regulation = relationship("RegulationDB")

    __table_args__ = (
        Index('ix_module_regulation', 'module_id', 'regulation_id', unique=True),
    )


class ModuleRiskDB(Base):
    """
    Service-specific risks aggregated from requirements and controls.
    """
    __tablename__ = 'compliance_module_risks'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    module_id = Column(String(36), ForeignKey('compliance_service_modules.id'), nullable=False, index=True)
    risk_id = Column(String(36), ForeignKey('compliance_risks.id'), nullable=False, index=True)

    # Module-specific assessment
    module_likelihood = Column(Integer)                                    # 1-5, may differ from global
    module_impact = Column(Integer)                                        # 1-5, may differ from global
    module_risk_level = Column(Enum(RiskLevelEnum))

    assessment_notes = Column(Text)                                        # Module-specific notes

    # Timestamps
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
    updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))

    # Relationships
    module = relationship("ServiceModuleDB", back_populates="module_risks")
    risk = relationship("RiskDB")

    __table_args__ = (
        Index('ix_module_risk', 'module_id', 'risk_id', unique=True),
    )


__all__ = [
    "ServiceTypeEnum",
    "RelevanceLevelEnum",
    "ServiceModuleDB",
    "ModuleRegulationMappingDB",
    "ModuleRiskDB",
]
