"""
Audit Session & Sign-Off models — Sprint 3 Phase 3.

Extracted from compliance/db/models.py as the first worked example of the
Phase 1 model split. The classes are re-exported from compliance.db.models
for backwards compatibility, so existing imports continue to work unchanged.

Tables:
- compliance_audit_sessions: Structured compliance audit sessions
- compliance_audit_signoffs:  Per-requirement sign-offs with digital signatures

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

import uuid
import enum
from datetime import datetime, timezone

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

from classroom_engine.database import Base


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

class AuditResultEnum(str, enum.Enum):
    """Result of an audit sign-off for a requirement."""
    COMPLIANT = "compliant"                    # Fully compliant
    COMPLIANT_WITH_NOTES = "compliant_notes"   # Compliant with observations
    NON_COMPLIANT = "non_compliant"            # Not compliant - remediation required
    NOT_APPLICABLE = "not_applicable"          # Not applicable to this audit
    PENDING = "pending"                        # Not yet reviewed


class AuditSessionStatusEnum(str, enum.Enum):
    """Status of an audit session."""
    DRAFT = "draft"                            # Session created, not started
    IN_PROGRESS = "in_progress"                # Audit in progress
    COMPLETED = "completed"                    # All items reviewed
    ARCHIVED = "archived"                      # Historical record


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

class AuditSessionDB(Base):
    """
    Audit session for structured compliance reviews.

    Enables auditors to:
    - Create named audit sessions (e.g., "Q1 2026 GDPR Audit")
    - Track progress through requirements
    - Sign off individual items with digital signatures
    - Generate audit reports
    """
    __tablename__ = 'compliance_audit_sessions'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    name = Column(String(200), nullable=False)                              # e.g., "Q1 2026 Compliance Audit"
    description = Column(Text)

    # Auditor information
    auditor_name = Column(String(100), nullable=False)                      # e.g., "Dr. Thomas Müller"
    auditor_email = Column(String(200))
    auditor_organization = Column(String(200))                              # External auditor company

    # Session scope
    status = Column(Enum(AuditSessionStatusEnum), default=AuditSessionStatusEnum.DRAFT)
    regulation_ids = Column(JSON)                                           # Filter: ["GDPR", "AIACT"] or null for all

    # Progress tracking
    total_items = Column(Integer, default=0)
    completed_items = Column(Integer, default=0)
    compliant_count = Column(Integer, default=0)
    non_compliant_count = Column(Integer, default=0)

    # Timestamps
    created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
    started_at = Column(DateTime)                                           # When audit began
    completed_at = Column(DateTime)                                         # When audit finished
    updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))

    # Relationships
    signoffs = relationship("AuditSignOffDB", back_populates="session", cascade="all, delete-orphan")

    __table_args__ = (
        Index('ix_audit_session_status', 'status'),
        Index('ix_audit_session_auditor', 'auditor_name'),
    )

    def __repr__(self):
        return f"<AuditSession {self.name} ({self.status.value})>"

    @property
    def completion_percentage(self) -> float:
        """Calculate completion percentage."""
        if self.total_items == 0:
            return 0.0
        return round((self.completed_items / self.total_items) * 100, 1)


class AuditSignOffDB(Base):
    """
    Individual sign-off for a requirement within an audit session.

    Features:
    - Records audit result (compliant, non-compliant, etc.)
    - Stores auditor notes and observations
    - Creates digital signature (SHA-256 hash) for tamper evidence
    """
    __tablename__ = 'compliance_audit_signoffs'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(String(36), ForeignKey('compliance_audit_sessions.id'), nullable=False, index=True)
    requirement_id = Column(String(36), ForeignKey('compliance_requirements.id'), nullable=False, index=True)

    # Audit result
    result = Column(Enum(AuditResultEnum), default=AuditResultEnum.PENDING)
    notes = Column(Text)                                                    # Auditor observations

    # Evidence references for this sign-off
    evidence_ids = Column(JSON)                                             # List of evidence IDs reviewed

    # Digital signature (SHA-256 hash of result + auditor + timestamp)
    signature_hash = Column(String(64))                                     # SHA-256 hex string
    signed_at = Column(DateTime)
    signed_by = Column(String(100))                                         # Auditor name at time of signing

    # 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
    session = relationship("AuditSessionDB", back_populates="signoffs")
    requirement = relationship("RequirementDB")

    __table_args__ = (
        Index('ix_signoff_session_requirement', 'session_id', 'requirement_id', unique=True),
        Index('ix_signoff_result', 'result'),
    )

    def __repr__(self):
        return f"<AuditSignOff {self.requirement_id}: {self.result.value}>"

    def create_signature(self, auditor_name: str) -> str:
        """
        Create a digital signature for this sign-off.

        Returns SHA-256 hash of: result + requirement_id + auditor_name + timestamp
        """
        import hashlib

        timestamp = datetime.now(timezone.utc).isoformat()
        data = f"{self.result.value}|{self.requirement_id}|{auditor_name}|{timestamp}"
        signature = hashlib.sha256(data.encode()).hexdigest()

        self.signature_hash = signature
        self.signed_at = datetime.now(timezone.utc)
        self.signed_by = auditor_name

        return signature


__all__ = [
    "AuditResultEnum",
    "AuditSessionStatusEnum",
    "AuditSessionDB",
    "AuditSignOffDB",
]
