"""
Network model for network segments and VLANs.

Networks represent network segments, VLANs, VPN networks, and other
logical or physical network divisions.
"""

from typing import Optional

from sqlalchemy import CHAR, CheckConstraint, ForeignKey, Index, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column

from .base import Base, TimestampMixin, UUIDMixin


class Network(Base, UUIDMixin, TimestampMixin):
    """
    Network model representing network segments and VLANs.

    Tracks network segments including LANs, VPNs, VLANs, isolated networks,
    and DMZs with CIDR notation, gateway IPs, and VLAN IDs.

    Attributes:
        client_id: Reference to the client
        site_id: Reference to the site
        network_name: Name of the network
        network_type: Type of network (lan, vpn, vlan, isolated, dmz)
        cidr: Network CIDR notation (e.g., "192.168.0.0/24")
        gateway_ip: Gateway IP address
        vlan_id: VLAN ID if applicable
        notes: Additional notes
        created_at: When the network was created
    """

    __tablename__ = "networks"

    # Foreign keys
    client_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("clients.id", ondelete="CASCADE"),
        doc="Reference to the client"
    )

    site_id: Mapped[Optional[str]] = mapped_column(
        CHAR(36),
        ForeignKey("sites.id", ondelete="CASCADE"),
        doc="Reference to the site"
    )

    # Network identification
    network_name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        doc="Name of the network"
    )

    network_type: Mapped[Optional[str]] = mapped_column(
        String(50),
        doc="Type: lan, vpn, vlan, isolated, dmz"
    )

    # Network configuration
    cidr: Mapped[str] = mapped_column(
        String(100),
        nullable=False,
        doc="Network CIDR notation (e.g., '192.168.0.0/24')"
    )

    gateway_ip: Mapped[Optional[str]] = mapped_column(
        String(45),
        doc="Gateway IP address"
    )

    vlan_id: Mapped[Optional[int]] = mapped_column(
        Integer,
        doc="VLAN ID if applicable"
    )

    # Notes
    notes: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="Additional notes"
    )


    # Constraints and indexes
    __table_args__ = (
        CheckConstraint(
            "network_type IN ('lan', 'vpn', 'vlan', 'isolated', 'dmz')",
            name="ck_networks_type"
        ),
        Index("idx_networks_client", "client_id"),
        Index("idx_networks_site", "site_id"),
    )

    def __repr__(self) -> str:
        """String representation of the network."""
        return f"<Network(network_name='{self.network_name}', cidr='{self.cidr}')>"
