from models.base import Base
from sqlalchemy import Boolean, Column, DateTime, Integer, String
from sqlalchemy.sql import func


class User(Base):
    """Mirror of the Atoms Cloud builtin users table.

    IMPORTANT: Do NOT add columns here. Local-auth-only fields
    (password_hash, auth_provider, is_active) live on
    :class:`LocalAuthProfile` keyed by ``user_id`` to keep the builtin
    users table untouched.
    """

    __tablename__ = "users"

    id = Column(String(255), primary_key=True, index=True)  # platform sub OR "local:<uuid>"
    email = Column(String(255), nullable=False, index=True)
    name = Column(String(255), nullable=True)
    role = Column(String(50), default="user", nullable=False)  # user/admin
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    last_login = Column(DateTime(timezone=True), nullable=True)


class LocalAuthProfile(Base):
    """Side-table holding local-auth-only fields for each ``User``.

    Created separately so the shared/builtin ``users`` table is not modified.
    A row exists only for users who have a local password or have been
    explicitly disabled. OIDC/platform users may have no row at all, which is
    equivalent to ``auth_provider='platform'`` and ``is_active=True``.
    """

    __tablename__ = "local_auth_profiles"

    user_id = Column(String(255), primary_key=True, index=True)
    password_hash = Column(String(255), nullable=True)
    auth_provider = Column(String(50), default="platform", nullable=False)  # platform | local
    is_active = Column(Boolean, default=True, nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class OIDCState(Base):
    __tablename__ = "oidc_states"

    id = Column(Integer, primary_key=True, index=True)
    state = Column(String(255), unique=True, index=True, nullable=False)
    nonce = Column(String(255), nullable=False)
    code_verifier = Column(String(255), nullable=False)
    expires_at = Column(DateTime(timezone=True), nullable=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())


class PasswordResetToken(Base):
    """One-time password-reset token for local accounts.

    We store only the SHA-256 hash of the token; the plaintext is emailed to
    the user and never persisted. Tokens expire after a short window and are
    consumed on first successful use.
    """

    __tablename__ = "password_reset_tokens"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(String(255), nullable=False, index=True)
    token_hash = Column(String(255), unique=True, nullable=False, index=True)
    expires_at = Column(DateTime(timezone=True), nullable=False)
    used_at = Column(DateTime(timezone=True), nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())