from sqlalchemy import Column, Integer, String, Boolean, Float, Date, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import relationship, mapped_column, composite, Mapped
from sqlalchemy.dialects import postgresql
import dataclasses

from .db import Base, engine

class User(Base):#класс пользователя
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True, unique=True)#айди пользователя
    nickname = Column(String) # никнейм пользователя
    hashed_password = Column(String) 
    name = Column(String, nullable=True)#имя пользователя
    surname = Column(String)#фамилия пользователя
    disabled = Column(Boolean, default=False)
    rating = Column(Integer, default=0) # рейтинг пользователя (показатель надежности)
    points = Column(Integer, default=0) # баллы пользователя (заслуги перед платформой)
    num_of_ratings = Column(Integer, default=0) # количество оценок (т.е. то, сколько раз другие пользователи оценили текущего)
    reg_date = Column(Date) # дата регистрации

    announcements = relationship("Announcement", secondary="announcementuser", back_populates="user", lazy='selectin')
    trashboxes_chosen = relationship("Trashbox", back_populates="user", lazy='selectin')

class Announcement(Base): #класс объявления
    __tablename__ = "announcements"

    id = Column(Integer, primary_key=True, index=True) # айди объявления
    user_id = Column(Integer, ForeignKey("users.id")) # айди создателя объявления
    name = Column(String) # название объявления
    category = Column(String) #категория продукта из объявления
    best_by = Column(Date) #срок годности продукта из объявления
    address = Column(String)
    longtitude = Column(Float)
    latitude = Column(Float)
    description = Column(String) #описание продукта в объявлении
    src = Column(String, nullable=True) #изображение продукта в объявлении
    metro = Column(String) #ближайщее метро от адреса нахождения продукта
    trashId = Column(Integer, nullable=True)
    booked_counter = Column(Integer, nullable=True) #количество забронировавших (0 - никто не забронировал)
    obsolete = Column(Boolean, default=False) # состояние объявления (по-умолчанию считаем его актуальным)

    user = relationship("User", secondary="announcementuser", back_populates="announcements")


class AnnouncementUser(Base):
    __tablename__ = "announcementuser"

    def __init__(self, an_id, b_u_id):
        self.announcement_id = an_id
        self.booking_user_id = b_u_id

    announcement_id = Column(Integer, ForeignKey("announcements.id"), primary_key=True) # id забронированного объявления
    booking_user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) # id пользователя, забронировавшего объявление
    


class Ratings(Base):
    __tablename__ = "ratings"

    def __init__(self, rated_user_id, user_giving_rating_id, rating_val):
        self.rated_user_id = rated_user_id
        self.user_giving_rating_id = user_giving_rating_id
        self.rating_value = rating_val

    rated_user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) # id пользователя, оставившего оценку
    user_giving_rating_id = Column(Integer, ForeignKey("users.id"), primary_key=True) # id оцениваемого пользователя
    rating_value = Column(Integer, primary_key=True) # оценка


class Trashbox(Base): #класс мусорных баков
    __tablename__ = "trashboxes"

    id = Column(Integer, primary_key=True, index=True)#айди 
    user_id = Column(Integer, ForeignKey("users.id")) # айди выбравшего мусорку
    name = Column(String, nullable=True)#название мусорки
    address = Column(String)
    latitude = Column(Float)
    longtitude = Column(Float)
    category = Column(String) #типы мусора (из тех, что возвращает API мусорки)
    date_of_choice = Column(Date) # Дата выбора мусорки пользователем

    user = relationship("User", back_populates="trashboxes_chosen")
    

class Poems(Base):#класс поэзии
    __tablename__ = "poems"

    id = Column(Integer, primary_key=True, index=True)  #айди 
    title = Column(String) # название стихотворения
    text = Column(String) # текст стихотворения
    author = Column(String) # автор стихотворения