from sqlalchemy import (
    Column,
    Integer,
    String,
    Text,
    DateTime,
    JSON,
    Float,
    Boolean,
    CheckConstraint,
    Index,
    text,
)
from .engine import Base
from datetime import datetime
from sqlalchemy.dialects.postgresql import ARRAY


class Users(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True, autoincrement=True)  # Внутренний ID записи
    user_id = Column(Integer, nullable=False, unique=True)


class AutoInfo(Base):
    __tablename__ = 'autoinfo'

    id = Column(Integer, primary_key=True, autoincrement=True)
    ad_id = Column(String(50), unique=True, nullable=False)
    name = Column(String(255), nullable=False)
    year = Column(Integer, nullable=True)
    usd_price = Column(Float, nullable=True)
    publish_time = Column(String(100), nullable=True)
    all_phones = Column(JSON, nullable=True)  # Список номеров хранится в формате JSON
    link = Column(Text, nullable=False)
    spam = Column(Boolean, default=False, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)  # Дата и время добавления



class filtersettings(Base):
    __tablename__ = 'filterUser'

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, nullable=False, unique=True)
    typeavto = Column(String(50), nullable=False)
    region_id = Column(JSON, nullable=True)
    year_first = Column(Integer, nullable=True)
    year_second = Column(Integer, nullable=True)
    price_first = Column(Float, nullable=True)
    price_second = Column(Float, nullable=True)
    # Режим работы: manual (только кнопка) / schedule (авто по окну и дням)
    run_mode = Column(String(20), nullable=False, default="manual")
    work_from = Column(String(5), nullable=False, default="09:00")  # ЧЧ:ММ
    work_to = Column(String(5), nullable=False, default="20:00")    # ЧЧ:ММ, same-day
    # Дни недели: 0=Пн … 6=Вс (как datetime.weekday())
    work_days = Column(JSON, nullable=True)


# Таблица статистики
class MessageLog(Base):
    __tablename__ = 'message_log'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(255), nullable=False)
    link = Column(Text, nullable=False)
    is_sent = Column(Boolean, default=False, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)  # Дата и время добавления


class MessageCounter(Base):
    __tablename__ = 'message_counter'

    id = Column(Integer, primary_key=True, autoincrement=True)
    successful = Column(Integer, default=0, nullable=False)   # количество успешно отправленных
    failed     = Column(Integer, default=0, nullable=False)   # количество неуспешных


class MessageTotals(Base):
    """
    Содержит суммарное количество всех отправленных (sent_total)
    и всех неотправленных/ошибочных (failed_total) сообщений
    за всё время работы системы. В таблице всегда ровно одна строка.
    """
    __tablename__ = 'message_totals'

    # фиксируем единственную строку с id = 1
    id = Column(Integer, primary_key=True, default=1)
    sent_total   = Column(Integer, default=0, nullable=False)
    failed_total = Column(Integer, default=0, nullable=False)

    # защита от случайной вставки второй строки
    __table_args__ = (
        CheckConstraint('id = 1', name='ck_message_totals_singleton'),
    )


class SmsSettings(Base):
    """
    Хранит настройки для SMS сообщений.
    В таблице всегда ровно одна строка с настройками.
    """
    __tablename__ = 'sms_settings'

    # фиксируем единственную строку с id = 1
    id = Column(Integer, primary_key=True, default=1)
    sms_text = Column(Text, default='TurboSMS приветствует Вас!', nullable=False)
    sender_name = Column(String(50), default='Buy_Auto', nullable=False)

    # защита от случайной вставки второй строки
    __table_args__ = (
        CheckConstraint('id = 1', name='ck_sms_settings_singleton'),
    )


class SentPhones(Base):
    """
    Отслеживает номера телефонов, на которые уже отправлялись SMS.
    Предотвращает повторную отправку на один и тот же номер.
    """
    __tablename__ = 'sent_phones'

    id = Column(Integer, primary_key=True, autoincrement=True)
    phone_number = Column(String(20), nullable=False, unique=True)  # Номер в международном формате
    ad_id = Column(String(50), nullable=True)  # ID объявления (для связи с AutoInfo)
    ad_name = Column(String(255), nullable=True)  # Название объявления
    sent_at = Column(DateTime, default=datetime.utcnow, nullable=False)  # Время отправки
    is_successful = Column(Boolean, default=True, nullable=False)  # Успешно ли отправлено


class PendingSms(Base):
    """
    Очередь SMS, найденных вне рабочих часов пользователя.
    Flush worker отправляет их, когда user снова внутри work_from/work_to.
    """
    __tablename__ = "pending_sms"
    __table_args__ = (
        # Один активный pending на номер (защита от гонок при параллельном enqueue).
        Index(
            "uq_pending_sms_phone_pending",
            "phone_number",
            unique=True,
            sqlite_where=text("status = 'pending'"),
        ),
    )

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, nullable=False, index=True)
    phone_number = Column(String(20), nullable=False, index=True)
    ad_id = Column(String(50), nullable=True)
    ad_name = Column(String(255), nullable=True)
    link = Column(Text, nullable=True)
    status = Column(String(20), nullable=False, default="pending", index=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, nullable=False)


