"""Command log model - immutable audit trail for all commands."""

from enum import Enum as PyEnum

from sqlalchemy import BigInteger, Column, DateTime, Index, Integer, Text
from sqlalchemy.dialects.postgresql import JSONB, UUID

from iot_db.models.base import Base


class CommandEventType(PyEnum):
    """Types of events logged for command lifecycle."""

    created = "created"
    processing = "processing"
    completed = "completed"
    failed = "failed"
    retry = "retry"
    cancelled = "cancelled"


class CommandLog(Base):
    """Immutable audit log for command execution.

    This table provides a complete audit trail of all command operations.
    Each command can have multiple log entries tracking its lifecycle
    from creation through completion or failure.

    Key features:
    - Immutable records (no updates allowed)
    - Full command data copy for historical reference
    - Event-based tracking of command lifecycle
    - Performance metrics (execution time)

    Example records for a single command:

    1. Created event:
        id: 1
        command_id: <command_uuid>
        tenant: <tenant_uuid>
        device_id: "supla_device_12345_ch1"
        platform: "supla"
        platform_device_id: "4702"
        action: "turn_off"
        params: {}
        event_type: "created"
        event_data: None
        created_by: "user:123"
        created_at: 2026-02-23T10:00:00Z
        execution_time_ms: None

    2. Completed event:
        id: 2
        command_id: <command_uuid>
        tenant: <tenant_uuid>
        device_id: "supla_device_12345_ch1"
        platform: "supla"
        platform_device_id: "4702"
        action: "turn_off"
        params: {}
        event_type: "completed"
        event_data: {"connected": true, "on": false}
        created_by: "user:123"
        created_at: 2026-02-23T10:00:05Z
        execution_time_ms: 245

    Attributes:
        id: Primary key (auto-increment BIGSERIAL)
        command_id: Reference to the command in command_queue (soft FK)
        tenant: Tenant UUID (multi-tenant support)

        # Command data copy (for historical reference)
        device_id: meter_id from dim_device
        platform: Target platform ("supla" or "chirpstack")
        platform_device_id: Platform-specific device ID
        action: Command action
        params: JSON parameters for the action

        # Event information
        event_type: Type of event (created, processing, completed, failed, retry, cancelled)
        event_data: JSON with event details (platform response, error message, etc.)

        # Audit fields
        created_by: Command initiator
        created_at: Event timestamp

        # Metrics
        execution_time_ms: Time taken to execute command (only for completed/failed)
    """

    __tablename__ = "command_log"

    # Primary key
    id = Column(BigInteger, primary_key=True, autoincrement=True)

    # Reference to command (soft FK - no cascade delete)
    command_id = Column(UUID(as_uuid=True), nullable=False, index=True)

    # Multi-tenant support
    tenant = Column(UUID(as_uuid=True), nullable=False)

    # Command data copy
    device_id = Column(Text, nullable=False)
    platform = Column(Text, nullable=False)
    platform_device_id = Column(Text, nullable=False)
    action = Column(Text, nullable=False)
    params = Column(JSONB, nullable=True)

    # Event information
    event_type = Column(Text, nullable=False)
    event_data = Column(JSONB, nullable=True)

    # Audit fields
    created_by = Column(Text, nullable=False)
    created_at = Column(
        DateTime(timezone=True),
        nullable=False,
        server_default="NOW()",
    )

    # Metrics
    execution_time_ms = Column(Integer, nullable=True)

    __table_args__ = (
        Index("idx_command_log_command", "command_id"),
        Index("idx_command_log_tenant", "tenant", "created_at"),
        Index("idx_command_log_device", "device_id", "created_at"),
    )

    def __repr__(self):
        return (
            f"<CommandLog(id={self.id}, command_id={self.command_id}, "
            f"event_type={self.event_type})>"
        )
