"""
Site model for client physical locations.

Sites represent physical locations for clients including network configuration,
VPN settings, and gateway information.
"""

from typing import Optional

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

from .base import Base, TimestampMixin, UUIDMixin


class Site(Base, UUIDMixin, TimestampMixin):
    """
    Site model representing client physical locations.

    Tracks physical sites for clients with network configuration including
    subnets, VPN settings, gateway IPs, and DNS servers.

    Attributes:
        client_id: Reference to the client this site belongs to
        name: Site name (e.g., "Main Office", "SLC - Salt Lake City")
        network_subnet: Network subnet for the site (e.g., "172.16.9.0/24")
        vpn_required: Whether VPN is required to access this site
        vpn_subnet: VPN subnet if applicable (e.g., "192.168.1.0/24")
        gateway_ip: Gateway IP address (IPv4 or IPv6)
        dns_servers: JSON array of DNS server addresses
        notes: Additional notes about the site
    """

    __tablename__ = "sites"

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

    # Site identification
    name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        doc="Site name (e.g., 'Main Office', 'SLC - Salt Lake City')"
    )

    # Network configuration
    network_subnet: Mapped[Optional[str]] = mapped_column(
        String(100),
        doc="Network subnet for the site (e.g., '172.16.9.0/24')"
    )

    # VPN configuration
    vpn_required: Mapped[bool] = mapped_column(
        Boolean,
        default=False,
        server_default="0",
        nullable=False,
        doc="Whether VPN is required to access this site"
    )

    vpn_subnet: Mapped[Optional[str]] = mapped_column(
        String(100),
        doc="VPN subnet if applicable (e.g., '192.168.1.0/24')"
    )

    # Gateway and DNS
    gateway_ip: Mapped[Optional[str]] = mapped_column(
        String(45),
        doc="Gateway IP address (IPv4 or IPv6)"
    )

    dns_servers: Mapped[Optional[str]] = mapped_column(
        Text,
        doc="JSON array of DNS server addresses"
    )

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

    # Indexes
    __table_args__ = (
        Index("idx_sites_client", "client_id"),
    )

    def __repr__(self) -> str:
        """String representation of the site."""
        return f"<Site(name='{self.name}', client_id='{self.client_id}')>"
