"""
Klausur-Service Erwartungshorizont Models

Data classes for BYOEH (Bring-Your-Own-Expectation-Horizon).
"""

from dataclasses import dataclass
from datetime import datetime
from typing import Optional, Dict, Any

from .enums import EHStatus


@dataclass
class Erwartungshorizont:
    """An encrypted Erwartungshorizont (expectation horizon)."""
    id: str
    tenant_id: str
    teacher_id: str
    title: str
    subject: str
    niveau: str  # 'eA' or 'gA'
    year: int
    aufgaben_nummer: Optional[str]
    encryption_key_hash: str
    salt: str
    encrypted_file_path: str
    file_size_bytes: int
    original_filename: str
    rights_confirmed: bool
    rights_confirmed_at: Optional[datetime]
    status: EHStatus
    chunk_count: int
    indexed_at: Optional[datetime]
    error_message: Optional[str]
    training_allowed: bool  # ALWAYS FALSE
    created_at: datetime
    deleted_at: Optional[datetime]

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        status_value = self.status.value if hasattr(self.status, 'value') else self.status
        return {
            'id': self.id,
            'tenant_id': self.tenant_id,
            'teacher_id': self.teacher_id,
            'title': self.title,
            'subject': self.subject,
            'niveau': self.niveau,
            'year': self.year,
            'aufgaben_nummer': self.aufgaben_nummer,
            'status': status_value,
            'chunk_count': self.chunk_count,
            'rights_confirmed': self.rights_confirmed,
            'rights_confirmed_at': self.rights_confirmed_at.isoformat() if self.rights_confirmed_at else None,
            'indexed_at': self.indexed_at.isoformat() if self.indexed_at else None,
            'file_size_bytes': self.file_size_bytes,
            'original_filename': self.original_filename,
            'training_allowed': self.training_allowed,
            'created_at': self.created_at.isoformat(),
            'deleted_at': self.deleted_at.isoformat() if self.deleted_at else None
        }


@dataclass
class EHRightsConfirmation:
    """Rights confirmation for an Erwartungshorizont upload."""
    id: str
    eh_id: str
    teacher_id: str
    confirmation_type: str  # 'upload' | 'annual'
    confirmation_text: str
    ip_address: Optional[str]
    user_agent: Optional[str]
    confirmed_at: datetime

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        return {
            'id': self.id,
            'eh_id': self.eh_id,
            'teacher_id': self.teacher_id,
            'confirmation_type': self.confirmation_type,
            'confirmation_text': self.confirmation_text,
            'confirmed_at': self.confirmed_at.isoformat()
        }


@dataclass
class EHAuditLogEntry:
    """Audit log entry for EH operations."""
    id: str
    eh_id: Optional[str]
    tenant_id: str
    user_id: str
    action: str  # upload, index, rag_query, download, delete
    details: Optional[Dict]
    ip_address: Optional[str]
    user_agent: Optional[str]
    created_at: datetime

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        return {
            'id': self.id,
            'eh_id': self.eh_id,
            'tenant_id': self.tenant_id,
            'user_id': self.user_id,
            'action': self.action,
            'details': self.details,
            'created_at': self.created_at.isoformat()
        }


@dataclass
class EHKeyShare:
    """Encrypted passphrase share for authorized users."""
    id: str
    eh_id: str
    user_id: str
    encrypted_passphrase: str  # Passphrase encrypted with recipient's public key
    passphrase_hint: str  # Optional hint for the passphrase
    granted_by: str
    granted_at: datetime
    role: str  # 'second_examiner', 'third_examiner', 'supervisor'
    klausur_id: Optional[str]  # Link to specific Klausur if applicable
    active: bool

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        return {
            'id': self.id,
            'eh_id': self.eh_id,
            'user_id': self.user_id,
            'passphrase_hint': self.passphrase_hint,
            'granted_by': self.granted_by,
            'granted_at': self.granted_at.isoformat(),
            'role': self.role,
            'klausur_id': self.klausur_id,
            'active': self.active
        }


@dataclass
class EHKlausurLink:
    """Link between an EH and a Klausur."""
    id: str
    eh_id: str
    klausur_id: str
    linked_by: str
    linked_at: datetime

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        return {
            'id': self.id,
            'eh_id': self.eh_id,
            'klausur_id': self.klausur_id,
            'linked_by': self.linked_by,
            'linked_at': self.linked_at.isoformat()
        }


@dataclass
class EHShareInvitation:
    """Invitation to share an EH with another user."""
    id: str
    eh_id: str
    inviter_id: str  # User who sent the invitation
    invitee_id: str  # User receiving the invitation
    invitee_email: str  # Email for notification
    role: str  # Target role for the invitee
    klausur_id: Optional[str]  # Optional link to specific Klausur
    message: Optional[str]  # Optional message from inviter
    status: str  # 'pending', 'accepted', 'declined', 'expired', 'revoked'
    expires_at: datetime  # Invitation expiration
    created_at: datetime
    accepted_at: Optional[datetime]
    declined_at: Optional[datetime]

    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization."""
        return {
            'id': self.id,
            'eh_id': self.eh_id,
            'inviter_id': self.inviter_id,
            'invitee_id': self.invitee_id,
            'invitee_email': self.invitee_email,
            'role': self.role,
            'klausur_id': self.klausur_id,
            'message': self.message,
            'status': self.status,
            'expires_at': self.expires_at.isoformat(),
            'created_at': self.created_at.isoformat(),
            'accepted_at': self.accepted_at.isoformat() if self.accepted_at else None,
            'declined_at': self.declined_at.isoformat() if self.declined_at else None
        }
