"""Script Builder session and message models.

Tracks AI-powered script generation conversations.
"""
import uuid
from datetime import datetime, timezone
from typing import Optional, TYPE_CHECKING

from sqlalchemy import String, Text, DateTime, ForeignKey, Integer
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID

from app.core.database import Base

if TYPE_CHECKING:
    from app.models.user import User


class ScriptBuilderSession(Base):
    """A conversation session in the AI Script Builder."""
    __tablename__ = "script_builder_sessions"

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
    )
    user_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("users.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    account_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("accounts.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    team_id: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("teams.id", ondelete="SET NULL"),
        nullable=True,
    )
    language: Mapped[str] = mapped_column(
        String(30), nullable=False, default="powershell",
        comment="Script language: powershell, bash, python",
    )
    title: Mapped[Optional[str]] = mapped_column(
        String(200), nullable=True,
        comment="Auto-generated from first AI response",
    )
    latest_script: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True,
        comment="Most recent generated script for quick access",
    )
    latest_script_filename: Mapped[Optional[str]] = mapped_column(
        String(200), nullable=True,
        comment="Filename of the latest generated script",
    )
    ai_session_id: Mapped[Optional[uuid.UUID]] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("ai_sessions.id", ondelete="SET NULL"),
        nullable=True,
        comment="Link to FlowPilot session if launched from there",
    )
    origin: Mapped[str] = mapped_column(
        String(20),
        nullable=False,
        default="standalone",
        comment=(
            "Session origin — 'standalone' (from /script-builder) or "
            "'pilot_inline' (from FlowPilot Script Builder tab). "
            "Invariant: pilot_inline rows must have ai_session_id set."
        ),
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True),
        default=lambda: datetime.now(timezone.utc),
        onupdate=lambda: datetime.now(timezone.utc),
    )

    # Relationships
    user: Mapped["User"] = relationship("User")
    message_records: Mapped[list["ScriptBuilderMessage"]] = relationship(
        "ScriptBuilderMessage",
        back_populates="session",
        order_by="ScriptBuilderMessage.created_at",
        cascade="all, delete-orphan",
    )


class ScriptBuilderMessage(Base):
    """A single message in a Script Builder conversation."""
    __tablename__ = "script_builder_messages"

    id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
    )
    session_id: Mapped[uuid.UUID] = mapped_column(
        UUID(as_uuid=True),
        ForeignKey("script_builder_sessions.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    role: Mapped[str] = mapped_column(
        String(20), nullable=False, comment="user or assistant"
    )
    content: Mapped[str] = mapped_column(Text, nullable=False)
    script: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="Extracted script from AI response"
    )
    script_filename: Mapped[Optional[str]] = mapped_column(
        String(200), nullable=True
    )
    line_count: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    input_tokens: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    output_tokens: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
    )

    # Relationship
    session: Mapped["ScriptBuilderSession"] = relationship(
        "ScriptBuilderSession", back_populates="message_records"
    )
