"""Agent model for SysAdmin automation workers."""

import uuid
from datetime import datetime
from enum import Enum
from typing import TYPE_CHECKING

from sqlalchemy import DateTime, ForeignKey, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import Base, TimestampMixin, UUIDMixin

if TYPE_CHECKING:
    from app.models.registration_token import RegistrationToken
    from app.models.task import Task
    from app.models.tenant import Tenant


class AgentStatus(str, Enum):
    """Agent status values."""

    ONLINE = "online"
    OFFLINE = "offline"
    INVALID = "invalid"  # Agent with NULL tenant_id, must re-register


class Agent(UUIDMixin, TimestampMixin, Base):
    """
    Agent model representing a SysAdmin automation worker.

    Agents register with the orchestrator and receive tasks to execute.
    """

    __tablename__ = "agents"

    tenant_id: Mapped[uuid.UUID | None] = mapped_column(
        ForeignKey("tenants.id", ondelete="CASCADE"),
        nullable=True,
        index=True,
    )
    name: Mapped[str] = mapped_column(
        String(255),
        nullable=False,
    )
    version: Mapped[str] = mapped_column(
        String(50),
        nullable=False,
        default="",
    )
    status: Mapped[str] = mapped_column(
        String(20),
        nullable=False,
        default=AgentStatus.OFFLINE.value,
        index=True,
    )
    last_heartbeat: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True),
        nullable=True,
    )
    # Legacy field - kept for backward compatibility during migration
    # Will be removed after all agents migrate to new auth scheme
    token: Mapped[str] = mapped_column(
        Text,
        nullable=False,
        default="",
    )
    # New secure credential storage - SHA-256 hash of agent secret
    secret_hash: Mapped[str] = mapped_column(
        String(64),
        nullable=False,
        default="",
        comment="SHA-256 hash of the agent secret",
    )
    # Reference to the registration token used to create this agent
    registration_token_id: Mapped[uuid.UUID | None] = mapped_column(
        ForeignKey("registration_tokens.id", ondelete="SET NULL"),
        nullable=True,
        index=True,
    )

    # Relationships
    tenant: Mapped["Tenant | None"] = relationship(
        back_populates="agents",
    )
    tasks: Mapped[list["Task"]] = relationship(
        back_populates="agent",
        lazy="selectin",
    )
    registration_token: Mapped["RegistrationToken | None"] = relationship()

    def __repr__(self) -> str:
        return f"<Agent(id={self.id}, name={self.name}, status={self.status})>"
