from datetime import datetime

from sqlalchemy import (
    create_engine,
    Column,
    Integer,
    BigInteger,
    String,
    Boolean,
    DateTime,
    Text,
    UniqueConstraint,
    Index,
)
from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session

from config import Config


connect_args = {}
if Config.DATABASE_URL.startswith("sqlite"):
    connect_args["check_same_thread"] = False

engine = create_engine(
    Config.DATABASE_URL,
    connect_args=connect_args,
    pool_pre_ping=True,
)

db = scoped_session(
    sessionmaker(
        bind=engine,
        autoflush=False,
        expire_on_commit=False,
    )
)

Base = declarative_base()
Base.query = db.query_property()


class ChatSetting(Base):
    __tablename__ = "chat_settings"

    id = Column(Integer, primary_key=True)
    chat_id = Column(BigInteger, nullable=False, index=True)
    key = Column(String(100), nullable=False, index=True)
    value = Column(Text, nullable=True)

    __table_args__ = (UniqueConstraint("chat_id", "key", name="uq_chat_setting"),)


class AdminPermission(Base):
    __tablename__ = "admin_permissions"

    id = Column(Integer, primary_key=True)
    chat_id = Column(BigInteger, nullable=False, index=True)
    user_id = Column(BigInteger, nullable=False, index=True)
    permission = Column(String(50), nullable=False)

    __table_args__ = (
        UniqueConstraint("chat_id", "user_id", "permission", name="uq_admin_permission"),
    )


class Warning(Base):
    __tablename__ = "warnings"

    id = Column(Integer, primary_key=True)
    chat_id = Column(BigInteger, nullable=False, index=True)
    user_id = Column(BigInteger, nullable=False, index=True)
    admin_id = Column(BigInteger, nullable=True)
    reason = Column(Text, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)

    __table_args__ = (Index("ix_warning_chat_user", "chat_id", "user_id"),)


class Sponsor(Base):
    __tablename__ = "sponsors"

    id = Column(Integer, primary_key=True)
    sponsor_chat_id = Column(BigInteger, nullable=False, unique=True)
    title = Column(String(255), nullable=True)
    link = Column(String(500), nullable=True)
    active = Column(Boolean, default=True)
    added_by = Column(BigInteger, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow)


class RecentMessage(Base):
    __tablename__ = "recent_messages"

    id = Column(Integer, primary_key=True)
    chat_id = Column(BigInteger, nullable=False, index=True)
    user_id = Column(BigInteger, nullable=False, index=True)
    text_hash = Column(String(64), nullable=False, index=True)
    text = Column(Text, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, index=True)


class RateEvent(Base):
    __tablename__ = "rate_events"

    id = Column(Integer, primary_key=True)
    chat_id = Column(BigInteger, nullable=False, index=True)
    user_id = Column(BigInteger, nullable=False, index=True)
    event = Column(String(30), default="message")
    created_at = Column(DateTime, default=datetime.utcnow, index=True)


def init_db():
    Base.metadata.create_all(engine)