"""Pydantic schemas for network diagrams."""
from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, Field


class Position(BaseModel):
    x: float
    y: float


class DeviceProperties(BaseModel):
    hostname: str | None = None
    ip: str | None = None
    subnet: str | None = None
    vendor: str | None = None
    model: str | None = None
    role: str | None = None
    vlan: str | None = None
    notes: str | None = None
    status: str = Field(default="unknown", pattern=r"^(unknown|online|offline|degraded)$")


class NodeStyle(BaseModel):
    width: float | None = None
    height: float | None = None


class DiagramNode(BaseModel):
    id: str
    type: str
    label: str
    position: Position
    properties: DeviceProperties = Field(default_factory=DeviceProperties)
    nodeType: str | None = None
    style: NodeStyle | None = None
    parentId: str | None = None


class DiagramEdge(BaseModel):
    id: str
    source: str
    target: str
    label: str | None = None
    connectionType: str = "ethernet"
    speed: str | None = None
    notes: str | None = None
    routing: str | None = None


class NetworkDiagramCreate(BaseModel):
    name: str = Field(min_length=1, max_length=255)
    client_name: str | None = None
    asset_name: str | None = None
    description: str | None = None
    nodes: list[DiagramNode] = Field(default_factory=list)
    edges: list[DiagramEdge] = Field(default_factory=list)


class NetworkDiagramUpdate(BaseModel):
    name: str | None = Field(default=None, min_length=1, max_length=255)
    client_name: str | None = None
    asset_name: str | None = None
    description: str | None = None
    nodes: list[DiagramNode] | None = None
    edges: list[DiagramEdge] | None = None


class NetworkDiagramResponse(BaseModel):
    id: UUID
    account_id: UUID
    name: str
    client_name: str | None = None
    asset_name: str | None = None
    description: str | None = None
    nodes: list[DiagramNode] = Field(default_factory=list)
    edges: list[DiagramEdge] = Field(default_factory=list)
    thumbnail_url: str | None = None
    is_archived: bool = False
    created_by: UUID | None = None
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class NetworkDiagramListItem(BaseModel):
    id: UUID
    name: str
    client_name: str | None = None
    description: str | None = None
    node_count: int = 0
    category_counts: dict[str, int] = Field(default_factory=dict)
    thumbnail_url: str | None = None
    created_by: UUID | None = None
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class ExistingBounds(BaseModel):
    minX: float
    maxX: float
    minY: float
    maxY: float


class AIGenerateRequest(BaseModel):
    description: str = Field(min_length=1, max_length=5000)
    client_name: str | None = None
    mode: str = Field(default="replace", pattern=r"^(replace|merge)$")
    existingBounds: ExistingBounds | None = None


class AIGenerateResponse(BaseModel):
    nodes: list[DiagramNode]
    edges: list[DiagramEdge]
    suggestedName: str | None = None
    notes: str | None = None


class DiagramImportRequest(BaseModel):
    schemaVersion: int = Field(ge=1, le=1)
    name: str = Field(min_length=1, max_length=255)
    client_name: str | None = None
    description: str | None = None
    nodes: list[DiagramNode] = Field(default_factory=list)
    edges: list[DiagramEdge] = Field(default_factory=list)


class DiagramImportResponse(BaseModel):
    diagram: NetworkDiagramResponse
    warnings: list[str] = Field(default_factory=list)


class DiagramExportResponse(BaseModel):
    schemaVersion: int = 1
    name: str
    client_name: str | None = None
    description: str | None = None
    nodes: list[DiagramNode]
    edges: list[DiagramEdge]
    exportedAt: str
