from sqlalchemy import Column, Integer, String, Sequence, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, Text, ForeignKey, DateTime
from sqlalchemy.sql import func
from sqlalchemy import text

SQLALCHEMY_DATABASE_URL = "sqlite:///./chepuhagram.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
Base.metadata.create_all(bind=engine)

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, Sequence('user_id_seq', start=100), primary_key=True, index=True)
    first_name = Column(String(50), nullable=False, server_default="User")
    last_name = Column(String(50), nullable=True)
    username = Column(String, unique=True, index=True)
    about = Column(String, nullable=True)
    phone = Column(String(20), unique=True, nullable=True)
    email = Column(String(255), unique=True, nullable=True)
    totp_secret = Column(String(32), nullable=True)
    totp_temp_secret = Column(String(32), nullable=True)  # Temporary secret until verified
    hashed_password = Column(String)
    public_key = Column(String, nullable=True)
    encrypted_private_key = Column(String, nullable=True)
    fcm_token = Column(String, nullable=True)
    avatar_file_id = Column(String, nullable=True)
    
    # Privacy settings
    show_email = Column(Integer, nullable=False, server_default="1")  # 1 = true, 0 = false
    show_phone = Column(Integer, nullable=False, server_default="1")
    show_avatar = Column(Integer, nullable=False, server_default="1")
    show_about = Column(Integer, nullable=False, server_default="1")
    show_username = Column(Integer, nullable=False, server_default="1")
    show_last_online = Column(Integer, nullable=False, server_default="1")
    last_online = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
    
class Message(Base):
    __tablename__ = "messages"
    id = Column(Integer, primary_key=True, index=True)
    sender_id = Column(Integer, ForeignKey("users.id"))
    receiver_id = Column(Integer, ForeignKey("users.id"))
    content = Column(Text) 
    timestamp = Column(DateTime(timezone=True), server_default=func.now())
    delivered_at = Column(DateTime(timezone=True), nullable=True)
    read_at = Column(DateTime(timezone=True), nullable=True)
    reply_to_id = Column(Integer, ForeignKey("messages.id"), nullable=True)
    reply_to_text = Column(Text, nullable=True)
    edited_at = Column(DateTime(timezone=True), nullable=True)

Base.metadata.create_all(bind=engine)


def _ensure_sqlite_message_columns():
    # Простая авто-миграция для SQLite без Alembic.
    # Добавляет колонки, если приложение обновилось на уже существующей БД.
    with engine.connect() as conn:
        cols = conn.execute(text("PRAGMA table_info(messages)")).fetchall()
        existing = {row[1] for row in cols}  # row[1] = name

        if "delivered_at" not in existing:
            conn.execute(text("ALTER TABLE messages ADD COLUMN delivered_at DATETIME"))
        if "read_at" not in existing:
            conn.execute(text("ALTER TABLE messages ADD COLUMN read_at DATETIME"))
        if "reply_to_id" not in existing:
            conn.execute(text("ALTER TABLE messages ADD COLUMN reply_to_id INTEGER REFERENCES messages(id)"))
        if "reply_to_text" not in existing:
            conn.execute(text("ALTER TABLE messages ADD COLUMN reply_to_text TEXT"))
        if "edited_at" not in existing:
            conn.execute(text("ALTER TABLE messages ADD COLUMN edited_at DATETIME"))
        conn.commit()


_ensure_sqlite_message_columns()


def _ensure_sqlite_user_columns():
    with engine.connect() as conn:
        cols = conn.execute(text("PRAGMA table_info(users)")).fetchall()
        existing = {row[1] for row in cols}

        if "about" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN about TEXT"))
        if "phone" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN phone VARCHAR(20)"))
        if "email" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN email VARCHAR(255)"))
        if "show_email" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_email INTEGER DEFAULT 1"))
        if "show_phone" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_phone INTEGER DEFAULT 1"))
        if "show_avatar" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_avatar INTEGER DEFAULT 1"))
        if "show_about" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_about INTEGER DEFAULT 1"))
        if "show_username" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_username INTEGER DEFAULT 1"))
        if "show_last_online" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN show_last_online INTEGER DEFAULT 1"))
        if "last_online" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN last_online DATETIME"))
            conn.execute(text("UPDATE users SET last_online = datetime('now')"))
        if "avatar_file_id" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN avatar_file_id VARCHAR(255)"))
        if "totp_temp_secret" not in existing:
            conn.execute(text("ALTER TABLE users ADD COLUMN totp_temp_secret VARCHAR(32)"))
        conn.commit()


_ensure_sqlite_user_columns()
