"""Command device mapping model - device to platform command capability mapping."""

from datetime import datetime

from sqlalchemy import Boolean, Column, DateTime, Index, Integer, Text, UniqueConstraint
from sqlalchemy.dialects.postgresql import ARRAY, JSONB, UUID

from iot_db.models.base import Base


class CommandDeviceMapping(Base):
    """Mapping of devices to their command capabilities on IoT platforms.

    This table stores the mapping between DWH device records (dim_device)
    and their command capabilities on specific IoT platforms. It enables
    the Command API to:
    - Resolve device_id to platform-specific identifiers
    - Validate which actions are supported by each device
    - Store platform-specific configuration

    Key features:
    - Multi-platform support (Supla, ChirpStack)
    - Action capability tracking per device
    - Platform-specific configuration storage
    - Active/inactive status for device availability

    Example records:

    Supla relay device:
        id: 1
        tenant: <tenant_uuid>
        device_id: "supla_device_12345_ch1"
        platform: "supla"
        platform_device_id: "4702"
        platform_config: {"function": "CONTROLLINGTHEGATEWAYLOCK"}
        supported_actions: ["turn_on", "turn_off", "open", "close"]
        is_active: True
        created_at: 2026-02-23T10:00:00Z
        updated_at: 2026-02-23T10:00:00Z

    Supla thermostat device:
        id: 2
        tenant: <tenant_uuid>
        device_id: "supla_device_67890_ch2"
        platform: "supla"
        platform_device_id: "4899"
        platform_config: {"function": "THERMOSTAT"}
        supported_actions: ["set_temperature", "turn_on", "turn_off"]
        is_active: True
        created_at: 2026-02-23T10:00:00Z
        updated_at: 2026-02-23T10:00:00Z

    ChirpStack UC300 device:
        id: 3
        tenant: <tenant_uuid>
        device_id: "chirpstack_a840411f4182c867"
        platform: "chirpstack"
        platform_device_id: "a840411f4182c867"
        platform_config: {"fPort": 85, "deviceProfile": "uc300"}
        supported_actions: ["set_report_interval", "set_digital_output", "reboot"]
        is_active: True
        created_at: 2026-02-23T10:00:00Z
        updated_at: 2026-02-23T10:00:00Z

    Attributes:
        id: Primary key (auto-increment)
        tenant: Tenant UUID (multi-tenant support)

        # Device identification
        device_id: meter_id from dim_device (business key)
        platform: Target platform ("supla" or "chirpstack")
        platform_device_id: Platform-specific device ID
            - For Supla: channel_id (e.g., "4702")
            - For ChirpStack: devEui (e.g., "a840411f4182c867")

        # Platform configuration
        platform_config: JSON with platform-specific settings

        # Capabilities
        supported_actions: Array of supported action names

        # Status
        is_active: Whether this mapping is active

        # Timestamps
        created_at: Record creation timestamp
        updated_at: Last update timestamp
    """

    __tablename__ = "command_device_mapping"

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

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

    # Device identification
    device_id = Column(Text, nullable=False)
    platform = Column(Text, nullable=False)
    platform_device_id = Column(Text, nullable=False)

    # Platform configuration
    platform_config = Column(JSONB, server_default="{}", nullable=False)

    # Capabilities
    supported_actions = Column(ARRAY(Text), nullable=False)

    # Status
    is_active = Column(Boolean, server_default="true", nullable=False)

    # Timestamps
    created_at = Column(
        DateTime(timezone=True),
        nullable=False,
        server_default="NOW()",
    )
    updated_at = Column(
        DateTime(timezone=True),
        nullable=False,
        server_default="NOW()",
        onupdate=datetime.utcnow,
    )

    __table_args__ = (
        # Unique constraint: one mapping per device per platform per tenant
        UniqueConstraint(
            "tenant",
            "device_id",
            "platform",
            name="uq_cmd_device_mapping_tenant_device_platform",
        ),
        # Index for device lookup
        Index(
            "idx_cmd_device_mapping_lookup",
            "tenant",
            "device_id",
            postgresql_where="is_active = true",
        ),
    )

    def __repr__(self):
        return (
            f"<CommandDeviceMapping(id={self.id}, device_id={self.device_id}, "
            f"platform={self.platform}, actions={self.supported_actions})>"
        )

    def supports_action(self, action: str) -> bool:
        """Check if this device supports the given action."""
        return action in (self.supported_actions or [])
