"""Subnet and VLAN models for network plugin."""

from shopdb.api import db, BaseModel


class VLAN(BaseModel):
    """
    VLAN definition.

    Represents a virtual LAN for network segmentation.
    """
    __tablename__ = 'vlans'

    vlanid = db.Column(db.Integer, primary_key=True)
    vlannumber = db.Column(db.Integer, unique=True, nullable=False, comment='VLAN ID number')
    name = db.Column(db.String(100), nullable=False, comment='VLAN name')
    description = db.Column(db.Text, nullable=True)

    # Optional classification
    vlantype = db.Column(
        db.String(50),
        nullable=True,
        comment='Type: data, voice, management, guest, etc.'
    )

    # Relationships
    subnets = db.relationship('Subnet', backref='vlan', lazy='dynamic')

    __table_args__ = (
        db.Index('idx_vlan_number', 'vlannumber'),
    )

    def __repr__(self):
        return f"<VLAN {self.vlannumber} - {self.name}>"

    def to_dict(self):
        """Convert to dictionary."""
        result = super().to_dict()
        result['subnetcount'] = self.subnets.count() if self.subnets else 0
        return result


class Subnet(BaseModel):
    """
    Subnet/IP network definition.

    Represents an IP subnet with optional VLAN association.
    """
    __tablename__ = 'subnets'

    subnetid = db.Column(db.Integer, primary_key=True)

    # Network definition
    cidr = db.Column(
        db.String(18),
        unique=True,
        nullable=False,
        comment='CIDR notation (e.g., 10.1.1.0/24)'
    )
    name = db.Column(db.String(100), nullable=False, comment='Subnet name')
    description = db.Column(db.Text, nullable=True)

    # Network details
    gatewayip = db.Column(
        db.String(15),
        nullable=True,
        comment='Default gateway IP address'
    )
    subnetmask = db.Column(
        db.String(15),
        nullable=True,
        comment='Subnet mask (e.g., 255.255.255.0)'
    )
    networkaddress = db.Column(
        db.String(15),
        nullable=True,
        comment='Network address (e.g., 10.1.1.0)'
    )
    broadcastaddress = db.Column(
        db.String(15),
        nullable=True,
        comment='Broadcast address (e.g., 10.1.1.255)'
    )

    # VLAN association
    vlanid = db.Column(
        db.Integer,
        db.ForeignKey('vlans.vlanid'),
        nullable=True
    )

    # Classification
    subnettype = db.Column(
        db.String(50),
        nullable=True,
        comment='Type: production, development, management, dmz, etc.'
    )

    # Location association
    locationid = db.Column(
        db.Integer,
        db.ForeignKey('locations.locationid'),
        nullable=True
    )

    # DHCP settings
    dhcpenabled = db.Column(db.Boolean, default=True, comment='DHCP enabled for this subnet')
    dhcprangestart = db.Column(db.String(15), nullable=True, comment='DHCP range start IP')
    dhcprangeend = db.Column(db.String(15), nullable=True, comment='DHCP range end IP')

    # DNS settings
    dns1 = db.Column(db.String(15), nullable=True, comment='Primary DNS server')
    dns2 = db.Column(db.String(15), nullable=True, comment='Secondary DNS server')

    # Relationships
    location = db.relationship('Location', backref='subnets')

    __table_args__ = (
        db.Index('idx_subnet_cidr', 'cidr'),
        db.Index('idx_subnet_vlan', 'vlanid'),
        db.Index('idx_subnet_location', 'locationid'),
    )

    def __repr__(self):
        return f"<Subnet {self.cidr} - {self.name}>"

    @property
    def vlan_number(self):
        """Get the VLAN number."""
        return self.vlan.vlannumber if self.vlan else None

    def to_dict(self):
        """Convert to dictionary with related data."""
        result = super().to_dict()

        # Add VLAN info
        if self.vlan:
            result['vlannumber'] = self.vlan.vlannumber
            result['vlanname'] = self.vlan.name

        # Add location info
        if self.location:
            result['locationname'] = self.location.locationname

        return result
