"""
ISMS Governance models (ISO 27001 Kapitel 4-6) — extracted from compliance/db/models.py.

Covers the documentation and planning side of the ISMS: scope, context,
policies, security objectives, and the Statement of Applicability. The audit
execution side (findings, CAPA, management reviews, internal audits, audit
trail, readiness checks) lives in ``isms_audit_models.py``.

Re-exported from ``compliance.db.models`` for backwards compatibility.

DO NOT change __tablename__, column names, or relationship strings — the
database schema is frozen.
"""

import uuid
import enum
from datetime import datetime, date, timezone

from sqlalchemy import (
    Column, String, Text, Integer, Boolean, DateTime, Date,
    ForeignKey, Enum, JSON, Index,
)

from classroom_engine.database import Base


# ============================================================================
# SHARED GOVERNANCE ENUMS
# ============================================================================

class ApprovalStatusEnum(str, enum.Enum):
    """Approval status for ISMS documents."""
    DRAFT = "draft"
    UNDER_REVIEW = "under_review"
    APPROVED = "approved"
    SUPERSEDED = "superseded"


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

class ISMSScopeDB(Base):
    """
    ISMS Scope Definition (ISO 27001 Kapitel 4.3)

    Defines the boundaries and applicability of the ISMS.
    This is MANDATORY for certification.
    """
    __tablename__ = 'compliance_isms_scope'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    version = Column(String(20), nullable=False, default="1.0")

    # Scope definition
    scope_statement = Column(Text, nullable=False)              # Main scope text
    included_locations = Column(JSON)                           # List of locations
    included_processes = Column(JSON)                           # List of processes
    included_services = Column(JSON)                            # List of services/products
    excluded_items = Column(JSON)                               # Explicitly excluded items
    exclusion_justification = Column(Text)                      # Why items are excluded

    # Boundaries
    organizational_boundary = Column(Text)                      # Legal entity, departments
    physical_boundary = Column(Text)                            # Locations, networks
    technical_boundary = Column(Text)                           # Systems, applications

    # Approval
    status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT)
    approved_by = Column(String(100))
    approved_at = Column(DateTime)
    approval_signature = Column(String(64))                     # SHA-256 hash

    # Validity
    effective_date = Column(Date)
    review_date = Column(Date)                                  # Next mandatory review

    # 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))
    created_by = Column(String(100))
    updated_by = Column(String(100))

    __table_args__ = (
        Index('ix_isms_scope_status', 'status'),
    )

    def __repr__(self):
        return f"<ISMSScope v{self.version} ({self.status.value})>"


class ISMSContextDB(Base):
    """
    ISMS Context (ISO 27001 Kapitel 4.1, 4.2)

    Documents internal/external issues and interested parties.
    """
    __tablename__ = 'compliance_isms_context'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    version = Column(String(20), nullable=False, default="1.0")

    # 4.1 Internal issues
    internal_issues = Column(JSON)                              # List of {"issue": "", "impact": "", "treatment": ""}

    # 4.1 External issues
    external_issues = Column(JSON)                              # List of {"issue": "", "impact": "", "treatment": ""}

    # 4.2 Interested parties
    interested_parties = Column(JSON)                           # List of {"party": "", "requirements": [], "relevance": ""}

    # Legal/regulatory requirements
    regulatory_requirements = Column(JSON)                      # DSGVO, AI Act, etc.
    contractual_requirements = Column(JSON)                     # Customer contracts

    # Analysis
    swot_strengths = Column(JSON)
    swot_weaknesses = Column(JSON)
    swot_opportunities = Column(JSON)
    swot_threats = Column(JSON)

    # Approval
    status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT)
    approved_by = Column(String(100))
    approved_at = Column(DateTime)

    # Review
    last_reviewed_at = Column(DateTime)
    next_review_date = Column(Date)

    # 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))

    def __repr__(self):
        return f"<ISMSContext v{self.version}>"


class ISMSPolicyDB(Base):
    """
    ISMS Policies (ISO 27001 Kapitel 5.2)

    Information security policy and sub-policies.
    """
    __tablename__ = 'compliance_isms_policies'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    policy_id = Column(String(30), unique=True, nullable=False, index=True)  # e.g., "POL-ISMS-001"

    # Policy details
    title = Column(String(200), nullable=False)
    policy_type = Column(String(50), nullable=False)            # "master", "operational", "technical"
    description = Column(Text)
    policy_text = Column(Text, nullable=False)                  # Full policy content

    # Scope
    applies_to = Column(JSON)                                   # Roles, departments, systems

    # Document control
    version = Column(String(20), nullable=False, default="1.0")
    status = Column(Enum(ApprovalStatusEnum), default=ApprovalStatusEnum.DRAFT)

    # Approval chain
    authored_by = Column(String(100))
    reviewed_by = Column(String(100))
    approved_by = Column(String(100))                           # Must be top management
    approved_at = Column(DateTime)
    approval_signature = Column(String(64))

    # Validity
    effective_date = Column(Date)
    review_frequency_months = Column(Integer, default=12)
    next_review_date = Column(Date)

    # References
    parent_policy_id = Column(String(36), ForeignKey('compliance_isms_policies.id'))
    related_controls = Column(JSON)                             # List of control_ids

    # Document path
    document_path = Column(String(500))                         # Link to full document

    # 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))

    __table_args__ = (
        Index('ix_policy_type_status', 'policy_type', 'status'),
    )

    def __repr__(self):
        return f"<ISMSPolicy {self.policy_id}: {self.title}>"


class SecurityObjectiveDB(Base):
    """
    Security Objectives (ISO 27001 Kapitel 6.2)

    Measurable information security objectives.
    """
    __tablename__ = 'compliance_security_objectives'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    objective_id = Column(String(30), unique=True, nullable=False, index=True)  # e.g., "OBJ-001"

    # Objective definition
    title = Column(String(200), nullable=False)
    description = Column(Text)
    category = Column(String(50))                               # "availability", "confidentiality", "integrity", "compliance"

    # SMART criteria
    specific = Column(Text)                                     # What exactly
    measurable = Column(Text)                                   # How measured
    achievable = Column(Text)                                   # Is it realistic
    relevant = Column(Text)                                     # Why important
    time_bound = Column(Text)                                   # Deadline

    # Metrics
    kpi_name = Column(String(100))
    kpi_target = Column(String(100))                            # Target value
    kpi_current = Column(String(100))                           # Current value
    kpi_unit = Column(String(50))                               # %, count, score
    measurement_frequency = Column(String(50))                  # monthly, quarterly

    # Responsibility
    owner = Column(String(100))
    accountable = Column(String(100))                           # RACI: Accountable

    # Status
    status = Column(String(30), default="active")               # active, achieved, not_achieved, cancelled
    progress_percentage = Column(Integer, default=0)

    # Timeline
    target_date = Column(Date)
    achieved_date = Column(Date)

    # Linked items
    related_controls = Column(JSON)
    related_risks = Column(JSON)

    # Approval
    approved_by = Column(String(100))
    approved_at = Column(DateTime)

    # 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))

    __table_args__ = (
        Index('ix_objective_status', 'status'),
        Index('ix_objective_category', 'category'),
    )

    def __repr__(self):
        return f"<SecurityObjective {self.objective_id}: {self.title}>"


class StatementOfApplicabilityDB(Base):
    """
    Statement of Applicability (SoA) - ISO 27001 Anhang A Mapping

    Documents which Annex A controls are applicable and why.
    This is MANDATORY for certification.
    """
    __tablename__ = 'compliance_soa'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))

    # ISO 27001:2022 Annex A reference
    annex_a_control = Column(String(20), nullable=False, index=True)  # e.g., "A.5.1"
    annex_a_title = Column(String(300), nullable=False)
    annex_a_category = Column(String(100))                      # "Organizational", "People", "Physical", "Technological"

    # Applicability decision
    is_applicable = Column(Boolean, nullable=False)
    applicability_justification = Column(Text, nullable=False)  # MUST be documented

    # Implementation status
    implementation_status = Column(String(30), default="planned")  # planned, partial, implemented, not_implemented
    implementation_notes = Column(Text)

    # Mapping to our controls
    breakpilot_control_ids = Column(JSON)                       # List of our control_ids that address this
    coverage_level = Column(String(20), default="full")         # full, partial, planned

    # Evidence
    evidence_description = Column(Text)
    evidence_ids = Column(JSON)                                 # Links to EvidenceDB

    # Risk-based justification (for exclusions)
    risk_assessment_notes = Column(Text)                        # If not applicable, explain why
    compensating_controls = Column(Text)                        # If partial, explain compensating measures

    # Approval
    reviewed_by = Column(String(100))
    reviewed_at = Column(DateTime)
    approved_by = Column(String(100))
    approved_at = Column(DateTime)

    # Version tracking
    version = Column(String(20), default="1.0")

    # 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))

    __table_args__ = (
        Index('ix_soa_annex_control', 'annex_a_control', unique=True),
        Index('ix_soa_applicable', 'is_applicable'),
        Index('ix_soa_status', 'implementation_status'),
    )

    def __repr__(self):
        return f"<SoA {self.annex_a_control}: {'Applicable' if self.is_applicable else 'N/A'}>"


__all__ = [
    "ApprovalStatusEnum",
    "ISMSScopeDB",
    "ISMSContextDB",
    "ISMSPolicyDB",
    "SecurityObjectiveDB",
    "StatementOfApplicabilityDB",
]
