from typing import List, Optional
from sqlalchemy import create_engine, String, select, ForeignKey
from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column, relationship


class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = 'users'

    id: Mapped[int] = mapped_column(primary_key=True)
    username: Mapped[str]
    passwd: Mapped[str]
    bndname: Mapped[str]
    newbnd: Mapped[bool]
    active: Mapped[bool]
    upstream: Mapped[bool]

    profiles: Mapped[List['Profile']] = relationship(
        back_populates='user', cascade='all, delete-orphan'
    )

    schedule: Mapped[List['Schedule']] = relationship(
        back_populates='user', cascade='all, delete-orphan'
    )

    queue: Mapped[List['Queue']] = relationship(
        back_populates='user', cascade='all, delete-orphan'
    )

    def __repr__(self) -> str:
        return f'User(id={self.id!r}, username={self.username!r}, password={self.passwd!r}, newbnd={self.newbnd})'

    def to_dict(self) -> dict:
        return {
            'id': self.id,
            'username': self.username,
            'bndname': self.bndname,
            'newbnd': self.newbnd,
            'active': self.active,
            'upstream': self.upstream,
            'profiles': [x.to_dict() for x in self.profiles],
            'schedule': [x.to_dict() for x in self.schedule],
            'queue': [x.to_dict() for x in self.queue],
        }


class Profile(Base):
    __tablename__ = 'profiles'

    id: Mapped[int] = mapped_column(primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
    scheme: Mapped[str]
    json: Mapped[str]

    user: Mapped['User'] = relationship(back_populates='profiles')

    def to_dict(self) -> dict:
        return {
            'id': self.id,
            'json': self.json,
        }


class Schedule(Base):
    __tablename__ = 'schedule'

    id: Mapped[int] = mapped_column(primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
    day_start: Mapped[int]
    hour_start: Mapped[int]
    minute_start: Mapped[int]
    day_end: Mapped[int]
    hour_end: Mapped[int]
    minute_end: Mapped[int]

    user: Mapped['User'] = relationship(back_populates='schedule')

    def to_dict(self) -> dict:
        return {
            'id': self.id,
            'day_start': self.day_start,
            'hour_start': self.hour_start,
            'minute_start': self.minute_start,
            'day_end': self.day_end,
            'hour_end': self.hour_end,
            'minute_end': self.minute_end,
        }


class Queue(Base):
    __tablename__ = 'queue'

    id: Mapped[int] = mapped_column(primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))
    commit_id: Mapped[str]
    schema: Mapped[str]

    user: Mapped['User'] = relationship(back_populates='queue')

    def to_dict(self) -> dict:
        return {
            'id': self.id,
            'commit_id': self.commit_id,
            'schema': self.schema,
        }


def connect_db():
    return create_engine("postgresql+psycopg://postgres:Root12345678@10.10.8.83:32101/db")
