"""
SQLAlchemy models for persistent user state & logs.
"""
from datetime import datetime
from typing import Optional, List
from sqlalchemy import (
    String, Integer, BigInteger, Text, DateTime, Boolean, JSON, Float
)
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy.ext.asyncio import AsyncAttrs


class Base(AsyncAttrs, DeclarativeBase):
    pass


class UserState(Base):
    """Per-user conversation state machine."""
    __tablename__ = "user_states"

    user_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    username: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    first_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    last_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)

    # State machine
    state: Mapped[str] = mapped_column(String(50), default="NEW", index=True)
    message_count: Mapped[int] = mapped_column(Integer, default=0)

    # Flags to prevent duplicate triggers
    welcome_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    invest_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    account_create_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    active_ask_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    bonus_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    task_2_sent: Mapped[bool] = mapped_column(Boolean, default=False)
    question_sent: Mapped[bool] = mapped_column(Boolean, default=False)

    # Collected data
    phone_number: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    detected_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    detected_age: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    detected_profession: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)

    # Timer
    bonus_sent_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)

    # Business connection (for replies on behalf of the account)
    business_connection_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)

    # Recent context (last N messages as JSON list)
    context_messages: Mapped[Optional[dict]] = mapped_column(JSON, default=list)

    # Meta
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(
        DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
    )
    done_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)


class ConversationLog(Base):
    """Audit log for every important event."""
    __tablename__ = "conversation_logs"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(BigInteger, index=True)
    username: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    direction: Mapped[str] = mapped_column(String(10))  # in / out / system
    content: Mapped[str] = mapped_column(Text)
    intent: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    triggered_script: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    state_before: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    state_after: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    phone_detected: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True)


class SystemConfig(Base):
    """Key-value store for runtime config (admin can change without restart)."""
    __tablename__ = "system_config"

    key: Mapped[str] = mapped_column(String(100), primary_key=True)
    value: Mapped[str] = mapped_column(Text)
    updated_at: Mapped[datetime] = mapped_column(
        DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
    )