"""
Client model for all client organizations.

Master table for MSP clients, internal projects, and client organizations.
"""

from typing import TYPE_CHECKING, Optional

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

from .base import Base, TimestampMixin, UUIDMixin

if TYPE_CHECKING:
    from .pending_task import PendingTask
    from .project import Project
    from .session import Session


class Client(Base, UUIDMixin, TimestampMixin):
    """
    Client model representing client organizations.

    Master table for all client organizations including MSP clients,
    internal projects, and project-based clients. Stores client identification,
    network information, and Microsoft 365 tenant details.

    Attributes:
        name: Client name (unique)
        type: Client type (msp_client, internal, project)
        network_subnet: Client network subnet (e.g., "192.168.0.0/24")
        domain_name: Active Directory domain or primary domain
        m365_tenant_id: Microsoft 365 tenant ID
        primary_contact: Primary contact person
        notes: Additional notes about the client
        is_active: Whether client is currently active
    """

    __tablename__ = "clients"

    # Client identification
    name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
        unique=True,
        doc="Client name (unique)"
    )

    type: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        doc="Client type: msp_client, internal, project"
    )

    # Network information
    network_subnet: Mapped[Optional[str]] = mapped_column(
        String(100),
        doc="Client network subnet (e.g., '192.168.0.0/24')"
    )

    domain_name: Mapped[Optional[str]] = mapped_column(
        String(255),
        doc="Active Directory domain or primary domain"
    )

    # Microsoft 365
    m365_tenant_id: Mapped[Optional[str]] = mapped_column(
        String(36),
        doc="Microsoft 365 tenant ID (UUID format)"
    )

    # Contact information
    primary_contact: Mapped[Optional[str]] = mapped_column(
        String(255),
        doc="Primary contact person"
    )

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

    # Status
    is_active: Mapped[bool] = mapped_column(
        Boolean,
        default=True,
        server_default="1",
        doc="Whether client is currently active"
    )

    # Relationships
    projects: Mapped[list["Project"]] = relationship(
        "Project",
        back_populates="client",
        cascade="all, delete-orphan",
        doc="Projects associated with this client"
    )

    sessions: Mapped[list["Session"]] = relationship(
        "Session",
        back_populates="client",
        doc="Sessions associated with this client"
    )

    pending_tasks: Mapped[list["PendingTask"]] = relationship(
        "PendingTask",
        back_populates="client",
        doc="Pending tasks associated with this client"
    )

    # Indexes
    __table_args__ = (
        Index("idx_clients_type", "type"),
        Index("idx_clients_name", "name"),
    )

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